I am creating a custom binding, named "myhandler". I need nothing in the initialize phase, and I do not want the update function to be executed the first time. The update member of ko.bindingHandlers, as said in the guide, is executed once at binding application, then whenever observable associated changes - I want to skip the binding application execution because it has not sense since other parts of the page are not ready for it.
In the observable associated, newID, passed in the html binding as follows, I have created a flag member in the view model, name bInitExecution (newID.bInitExecution).
<div><input id="objID" name="objID" data-bind="value: newID, myhandler: newID" /></div>
The member, which holds if handler should perform things in the first phase, is not an observable (but I also tried making it so without any change), it is a boolean and in the model it is fixed to true or false as needed, if update has to be performed also at first time or not.
newID = ko.observable();
//.... some other data
newID.bInitExecution = false
I expect that following code would skip first execution if bInitExecution is false, then execute always, while always execute if bInitExecution is true.
ko.bindingHandlers.myhandler = {
init: function init(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
//None needed here
},
update: function(element, valueAccessor, allBindings) {
if (valueAccessor().bInitExecution===true) {
//Do stuff
}
if (valueAccessor().bInitExecution===false) valueAccessor().bInitExecution=true;
}
};
The result is that, after the first execution, observables with bInitExecution set to true are always updated by myhandler, while the ones with bInitExecution set to false, even if valueAccessor().bInitExecution changes during binding apply as console.log before and after true assignment shows, without executing stuff, never executes myhandler.update again - as console.log placed on the head of the update function shows.
I do not understand why, someone has any idea? Thanks
In ko bindingHandler implementation, ko wraps the whole update
function in a ko.dependentObservable
(aka ko.computed
). That's how and why ko runs your update
function when data model changes.
It means if you didn't use the value of newID()
(as ko.unwrap(valueAccessor())
or valueAccessor()()
) in your update
function, the final ko.dependentObservable
wrapper IS NOT dependent on newID
. Hence ko would not run it again when newID
changes.
I guess you did not use the value of newID
in your //Do stuff...
.
update
I missed this part.
Even newID()
is accessed in //Do stuff
, the ko.computed
wrapper will never get chance to run again. Because in the first run of it, newID is not accessed, in fact there is no ko.observable
being accessed in the first run, so there is no dependency tracked by ko's auto tracking system.