Why Custom Binding?
This question might be raised when you read the title of this article. Well, you need to go for custom binding when you want more control and flexibility over elements and observables used. If you want to create your own interactive controls then the right way is to go for custom binding. Here is the goodexample for custom binding provided by KnockoutJS.
All the bindings available in the KnockoutJS are the sub properties of a "ko.bindingHandlers" object.
Creating Custom Binding
In order to create the custom binding, we need to add a property with your custom binding name and assign an object with two callback functions.
init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
},
update: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
}
}
Here you can see that we have added a property myCustomBindingName assigned with an object that has init and update callbacks. Let us see the callbacks in detail.
The init callback
The init callback function will be executed when the binding is applied the very first time. In this callback, we can have the initial setup necessary for the custom binding such as attaching events, setting up the initial state for variables and so on.
The init callback function will be executed when the binding is applied the very first time. In this callback, we can have the initial setup necessary for the custom binding such as attaching events, setting up the initial state for variables and so on.
Note: the init callback function will be called only one when the binding is applied.
The update callback
The update callback function will be called whenever the associated observable is changed. While binding your custom binding handler with the element, if you have associated/assigned an observable to your custom binding handler then the update callback will be executed whenever you change the associated/assigned observable.
For example, you have a custom binding handler, say "animateItem" that does some animation whenever an item is added to the collection. The animateItem binding handler accepts an observable that decides whether the added item should be animated on the screen or not based on the observable true/false value.
Whenever you update the observable, the update callback of your binding callback will be called with the updated value.
The parameters of callback functions
These init and update
callback functions have the same set of parameters. They are element,
valueAccessor, allBindingsAccessor, viewModel and bindingContext. Let us
discuss these one by one.
element | The DOM element on which our custom binding is applied. |
valueAccessor | The JavaScript function that will return the value assigned/associated with the binding. You can use the "ko.unwrap" utility function to get the value assigned |
allBindingAccessor | The JavaScript function that will return all the values assigned/associated with all the bindings bound with the current DOM. Suppose you have some other KO bindings say value, visible then the allBindingAccessor will give you those values and visible binding values also. |
viewModel | The viewmodel object that is bound to the entire page using "ko.applyBindings()". But when your binding is within the with binding or foreach binding then the viewModel parameter will have the $data context instead of the main viewModel. |
bindingContext | The binding context available for the DOM element. This parameter will have all other bindings ($parent, $parents and $root...) as a special property. |
Example
We will discuss
the custom binding with an example. We will create a custom binding
where we can display the change log for an input box.
<p>Change this value: <input data-bind="value: logEntry, valueUpdate: 'keyup'" /> </p><div data-bind="yourBindingName: logEntry">
<ul>
</ul>
</div>
In this example view, we have an input element bound to the logEntry observable assigned/associated with the value binding. And we have a div to which we have bound our custom binding "yourCoustomBinding". Since we have associated the logEntry observable with our custom bidning, the update callback function will be executed whenever the text in the input box is changed.
ko.bindingHandlers.yourBindingName = {
init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
// Setup the events, variables..
$(element).css("background-color", "rgb(228, 222, 222)");
},
update: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
var text = ko.unwrap(valueAccessor()); // Getting the update log text
$('ul').append('<il> The new text is : ' + text + '</il>');// Adding into the ul as il.
}
}
var viewModel = { logChange: ko.observable("Type some thing") };
ko.applyBindings(viewModel);
In the init callback
function, as an initial setup, we are setting the background color for
the change log container. When you start changing the text, the update callback will be called. In the update callback,
we are unwrapping the valueAccessor to get the value passed to our
custom binding. Then we are appending the changed text to the ul element
as an il item.
No comments:
Post a Comment