Calling jQuery.trigger ('change') on a hidden value breaks the knockout dependency

A bit of history about how we came across this ... Basically, we called trigger('change') on all of our input forms so that other observable knockouts know that their value was reset. But I really think this is a Knockout bug. By asking here to see if anyone else came across it (and StackOverflow is a much nicer interface than knockout gookout forums).

So, if you have a hidden input whose value is tied to data for the computed observable, and you call jQuery trigger('change') on it, it destroys the observable. If you drill through the code, you can see that on the view model object, the member object is replaced with the string of the last value on the calculated observable before you trigger the change event.

JS script showing failure in action: http://jsfiddle.net/2VvvE/1/

It uses console.log to output the object, so be warned if you try a browser without a console (cough IE). You can see that the dependent observable works fine until you click the "Break it" button, after which the value stops updating, and subsequent clicks display the same thing. If you comment out a line using a trigger ("change") on it and run the fiddle, you will see that it continues to work after pressing each button.

I apologize for not asking the real question - we already figured out the work where we call the trigger ("change") on inputs that are not hidden (a pretty simple jquery selector in case anyone is interested):

 $("#"+this.id+" form").each(function() { $(this).validate().resetForm(); this.reset(); // Do some actions on all the inputs, then filter before calling the trigger $(this).find('input,select').data('valid','true').filter(':not(:hidden)').trigger('change'); $(this).find('label,legend').removeClass('validated-error'); }); 

But I needed a verdict: a knockout error? Or am I not mistaken?

+4
source share
1 answer

You should not bind normal computed observable information to a read / write binding, such as value . This makes it overwrite in your model.

If you need, you can use a recordable computed observable . In this case, you may even have an empty write function: http://jsfiddle.net/rniemeyer/2VvvE/2/

The actual answer is that you really don't need to fire change events in the fields. The best way to handle this is to do it with your view model. On any observable or computed observable you can call the valueHasMutated() function to again notify all subscribers with the most recent value.

myObservable.valueHasMutated()

+4
source

All Articles