Here is a code snippet
<!DOCTYPE html>
<html>
<body>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.3.0/knockout-min.js"></script>
<div>
<div data-bind="yourBindingName: someValue ">
</div>
<button data-bind="click: clickme">Click me!</button>
</div>
<script type="text/javascript">
ko.bindingHandlers.yourBindingName = {
init: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
console.log("init");
},
update: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
console.log("update");
}
};
function ViewModel() {
this.someValue = ko.observable('test');
this.clickme = function () {
console.log('clickme');
this.someValue('');
}
}
ko.applyBindings(new ViewModel());
</script>
</body>
</html>
After clicking the "Click me!" button there is only 'clickme' in console and never 'update'. I expect the update function to be fired every time its bound value changed.
It does log an "update", but before you click the button. Knockout has run it once already, and whilst running has checked which observables your binding handler makes use of. Since you don't access valueAccessor
(or anything else) within it, it knows that it doesn't need to call update
on your binding handler when someValue
changes - it would be a waste of processing time. If you update your binding handler to use it, it will be called when someValue
changes, ie the first time you click the button:
ko.bindingHandlers.yourBindingName = {
init: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
console.log("init: " + valueAccessor()());
},
update: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
console.log("update: " + valueAccessor()());
}
};
Here's a demo:
ko.bindingHandlers.yourBindingName = {
init: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
console.log("init: " + valueAccessor()());
},
update: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
console.log("update: " + valueAccessor()());
}
};
function ViewModel() {
this.someValue = ko.observable('test');
this.clickme = function () {
console.log('clickme');
this.someValue('');
}
}
ko.applyBindings(new ViewModel());
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
(Open your dev tools to view the console)
<div data-bind="yourBindingName: someValue ">
</div>
<button data-bind="click: clickme">Click me!</button>