In knockoutjs, the existing binding function has been very strong, basically do not need to go into account expanded, however, there are exceptions to the scene, the face of this scene, still have to complete, knockoutJS provides custom bindings to extend the binding.
First, create a new Bind
Js file to try to create a new binding function, given format ko.bindingHandlers.xxx be extended in accordance with a binding.
ko.bindingHandlers.yourBindingName = { init: function(element, valueAccessor, allBindingsAccessor, viewModel) { // This will be called when the binding is first applied to an element // Set up any initial state, event handlers, etc. here }, update: function(element, valueAccessor, allBindingsAccessor, viewModel) { // This will be called once when the binding is first applied to an element, // and again whenever the associated observable changes value. // Update the DOM element based on the supplied values here. } };
Secondly, the binding can be completed in html, bound to the same usage comes.
<div data-bind="yourBindingName: someValue"> </div>
It should be noted here that, in a custom binding, the init and update methods are not necessarily to all the definitions, you can define only one of them.
Finally, the introduction of js files, placed in the knockoutjs
<script src="~/lib/knockout/knockout-3.5.0.js"></script> <script src="~/js/custombindings.js" asp-append-version="true"></script>
Second, the analytic function update
When a change occurs listening elements bound or associated monitor element changes, knockout will update the callback function, as long as there listening element changes associated, will be immediately update the callback function, several parameters are passed to the callback function update in.
-
element: The binding of the DOM element
-
valueAccessor: a JavaScript function, you can get the current value of the property on the binding of model application through valueAccessor (), using valueAccessor () do not need to pass parameters, and then by calling ko.unwrap () and passing valueAccessor () to get the attribute values can get the actual value.
-
allBindings: a JavaScript object, and all the property values bound by this object can access the DOM element to obtain the value of the specified attribute name based on the element by allBindings.get ( 'attribute name'), if this attribute is not present, returns undefined, or by allBindings.has ( 'attribute name') discriminates the attribute is present on the DOM element.
-
bindingContext: the context of the current binding element, you can access properties within the context of the current binding by the binding context and binding context within the context of a parent, sibling attributes within the context of (very powerful).
For example, you might want to control the visibility of an element by visible binding, but you want to animate the elements into hiding or displaying the time. Then you can customize your own binding to call the jQuery slideUp / slideDown function:
= ko.bindingHandlers.slideVisible { Update: function (Element, valueAccessor, allBindings) { // get property values var value = valueAccessor (); // get the current property values var valueUnwrapped = ko.unwrap (value); // from the current binding context other context attribute values acquired var DURATION = allBindings.get ( 'slideDuration') || 400; // 400ms DURATION iS the unless otherwise specified default // manipulating DOM elements IF (== valueUnwrapped to true ) $ (element). slideDown (DURATION); // the Make at The Element visible the else $(element).slideUp(duration); // Make the element invisible } };
Page, complete the binding directly in accordance with the format here, I would have been introduced into the custom file js block template page.
<div data-bind="slideVisible: giftWrap, slideDuration: 600">You have selected the option</div> <label><input type="checkbox" data-bind="checked: giftWrap" /> Gift wrap</label> @section Scripts{ <script type="text/javascript"> var viewModel = { giftWrap: ko.observable(true) }; $(function () { ko.applyBindings(viewModel);//完成绑定 }); </script> }
The effect can be seen from the definition of binding, the binding can be done in various places in order to achieve code reuse.
Third, the analytic function init
knockout when using self-defined binding calls your init function in the DOM elements, init function has two main purposes:
-
Set initial values for the DOM element
-
Registered event handlers, such as when the user clicks or edit the DOM element, you can change the state of the relevant observable value.
init function receives the same parameters and update functions, in accordance with the above example, the transformation and let slideVisible setting state of the element when the page is first displayed (but do not use any animation effects), in order to allow the user to change the animation in the future time and then executed.
= ko.bindingHandlers.slideVisible { the init: function (Element, valueAccessor) { var value = ko.unwrap (valueAccessor ()); $ (Element) .toggle (value); }, Update: function (Element, valueAccessor, allBindings) { // Get property value var value = valueAccessor (); // get the current property values var valueUnwrapped = ko.unwrap (value); // other context attribute values acquired from the current binding context var DURATION = allBindings.get ( ' slideDuration ') || 400; // 400ms DURATION IS The unless otherwise specified default // 操控DOM元素 if (valueUnwrapped == true) $(element).slideDown(duration); // Make the element visible else $(element).slideUp(duration); // Make the element invisible } };
Set the default viewModel in the giftWrap is false, when the page will start to see the corresponding direct Div is hidden, and will be displayed after clicking selected.
var viewModel = { giftWrap: ko.observable(true) };
Fourth, the modified DOM event listeners value
We have mastered the use of update callback when observable value changes update the DOM element. But in turn, it's a scene, for example, when a user do something to a DOM element, to update the relevant observable value. This can be registered by using an event handler callback init to change the relevant observable value.
ko.bindingHandlers.hasFocus = { init: function (element, valueAccessor) { $(element).focus(function () { var value = valueAccessor(); value(true); }); $(element).blur(function () { var value = valueAccessor(); value(false); }); }, update: function (element, valueAccessor) { var value = valueAccessor(); if (ko.unwrap(value)) element.focus(); else element.blur(); } };
For example, when the user clicks the input box display, hide when leaving, and modify the value monitor, control Enable Disable button.
<p>Name: <input data-bind="hasFocus: editingName" /></p> <div data-bind="visible: editingName">You're editing the name</div> <button data-bind="enable: !editingName(), click:function() { editingName(true) }">Edit name</button> @section Scripts{ <script type="text/javascript"> var viewModel = { giftWrap: ko.observable(to false ), editingName: ko.observable () }; $ ( function () { ko.applyBindings (viewModel); // complete the binding }); </ Script > }
The following effects can be obtained
You can also use custom binding on the virtual element
<!-- ko mybinding: somedata --> ... <!-- /ko -->
This completes the way custom binding, although less practical use, such as 28 principles, but as long as there is a scene can play useless.
Code Address: https://gitee.com/530521314/Partner.TreasureChest.git
2019-08-29,望技术有成后能回来看见自己的脚步