Reputation: 109
I do not understand the logic behind the following and I am hoping someone can help me understand. I am cleaning up a web app and have found the following lines of code. The app is an MVC app using Knockout.js. There are several custom bindings setup with the following structure:
var originalBindingInit = ko.bindingHandlers.binding.init;
var originalBindingUpdate = ko.bindingHandlers.binding.update;
ko.bindingHandlers.binding = {
init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
originalBindingInit(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext);
// Init code here...
},
update: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
originalBindingUpdate(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext);
// Update code here...
}
};
I do not understand why the init & update are being set to variables outside of the binding and then fired on the first line of each section of the binding? It would seem to me that you are creating a loop by doing this.
Can anyone shed some light on this? If it's covered in the knockout documentation, I have missed it and for that I do apologize.
Upvotes: 1
Views: 364
Reputation: 1288
Consider this:
var A = 1;
var originalA = A;
A = 2;
This way every place where A was used has new value and we can still use the old one. Since in JavaScript function is an object you can do the same for it. Keep the old one and overwrite it with some new functionality.
var functionA = function () {};
var originalFunctionA = functionA;
functionA = function () {};
It doesn't create the loop because it no longer has the same reference. Old reference is overwritten by new function. Perfect example is in your question. We've got a library knockout
with a method binding
. To extend it we can modify original source of the library but then we will have to do it each time library is updated. The more such modifications we need the harder maintaining will be.
So we write the new binding function at the place of original one. Nice, but now if we don't want to change it completely and just extend it a little bit we have to write everything it done in the first place. Why write it again when it was already written? We copy the original function to some new reference:
var originalBindingInit = ko.bindingHandlers.binding.init;
var originalBindingUpdate = ko.bindingHandlers.binding.update;
and then call it when we need it to do its job:
var bindingInit = function () {
// do sth befeore
originalBindingInit( someVariable );
// do sth after
}
We can put our extension at the beginning for some variable preparations and then call original function to do what it always does:
var someRoundedVariable = Math.round( someVariable );
originalBindingInit( someRoundedVariable );
In Knockout JS there is another way to do this by writing custom binding handler. And than call the original one.
ko.bindingHandlers.verifyValue = {
init: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
// do sth to verify value and than call other binding:
ko.bindingHandlers.value.init(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext);
},
update: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
// The rest of this binding is handled by the default value binding. Pass it on!
ko.bindingHandlers.value.update(element, newValueAccessor, allBindingsAccessor, viewModel, bindingContext);
}
};
Both have it cons and pros. Sometimes you can't modify View and have access to just ViewModel, sometimes you are sure you don't need the original binding without extensions (or keeping it is dangerous) other time you need modified binding in few places not all of them and then it's better to create new binding.
Upvotes: 1