I'm having a problem with knockout "checked" binding. It seems that "change" event at checkbox return old value, before it is updated(so if it was unchecked it will return false). I don't think that I can subscribe to the value since I have it inside object.
<tbody data-bind="foreach: Categories">
<tr>
<td><input type="checkbox" data-bind="checked: ShowOpened, event: { change: $root.CategoryChange }" /></td>
</tr>
</tbody>
<script type="text/javascript">
var Category = function (Id, Name, Order, ShowOpened) {
this.Id = Id;
this.Name = Name;
this.Order = Order;
this.ShowOpened = ShowOpened;
this.IsUpdated = ko.observable(false);
this.OldOrder = Order;
this.OldShowOpened = ShowOpened;
};
var ViewModel = {
Categories: ko.observableArray([]),
CategoryChange: function(pCategory) {
if(pCategory.Order != pCategory.OldOrder || pCategory.ShowOpened != pCategory.OldShowOpened)
pCategory.IsUpdated(true);
else
pCategory.IsUpdated(false);
}
};
ko.applyBindings(ViewModel);
</script>
So in this example I have ShowOpened checkbox that can trigger CategoryChange method that will change a variable inside object(that I need later to know what object are updated). But when the chechbox is changed it always send out the old value, triggering method, and then changes the value. Is there any way to fix this?
I also had this issue, but i couldn't use the subscribe solution because i was already subscribed to the same field with a ajax request that could reset the value. The code would then stay in a loop when you changed it. So i added the following workaround (its ugly but it works).
Then instead on listening to the change i would listen to the afterChange event.
I know its not the best solution, but in my case i had no other option.
Since you persisted on stating that the lack of
ko.observables
is not an issue, I've looked at it closer. It seems, that you are correct! Thechange
event is fired before the actual value is set. I'm afraid I do not know the reason for this.But there is an easy way to fix this: just change
change
event toclick
event:Remember, that you have to explicitly put
return true;
at the end ofclick
event handler. Otherwise the new value won't be set to checkbox.If you do not want to use
click
event, then you can do it the other way. Subscribe to changes ofShowOpened
:Try using
subscribe
instead of event binding. This should work nowOr as alternative (and in my opinion a better solution) you can use
dependentObservable
, now calledcomputed
. Here's how it would look like