Home  >  Article  >  Web Front-end  >  Knockout custom binding creation method_javascript skills

Knockout custom binding creation method_javascript skills

WBOY
WBOYOriginal
2016-05-16 15:23:161622browse

Overview

In addition to the built-in binding types of KO listed in the previous article (such as value, text, etc.), you can also create custom bindings.

Register your binding handler

ko.bindingHandlers.yourBindingName = {
  init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
    // 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, allBindings, viewModel, bindingContext) {
    // This will be called once when the binding is first applied to an element,
    // and again whenever any observables/computeds that are accessed change
    // Update the DOM element based on the supplied values here.
  }
}; 

Next you can use custom binding on any dom element:

<div data-bind="yourBindingName: someValue"> </div> 

Note: You do not have to provide both init and update callbacks in your handler, you can provide either one.

update callback

As the name suggests, when your monitoring attribute observable is updated, ko will automatically call your update callback.

It has the following parameters:

element: use this bound dom element;

valueAccessor: The currently bound model attribute value can be obtained by calling valueAccessor(). Calling ko.unwrap(valueAccessor()) can more conveniently obtain the observable value and ordinary value;

allBindings: All attribute values ​​bound to the model on this dom element, for example, call callBindings.get('name') to return the bound name attribute value (if it does not exist, return undefined), or call allBindings.has(' name') determines whether name is bound to the current dom;

viewModel : Deprecated in Knockout.3x, you can use bindingContext.$data or bindingContext.$rawData to get the current viewModel;

bindingContext: Binding context, you can call bindingContext.$data, bindingContext.$parent, bindingContext.$parents, etc. to obtain data;

Look at an example next. You may want to use visible binding to control the visibility of elements and add animation effects. In this case, you can create your custom binding:

ko.bindingHandlers.slideVisible = {
  update: function(element, valueAccessor, allBindings) {
    // First get the latest data that we're bound to
    var value = valueAccessor();
    // Next, whether or not the supplied model property is observable, get its current value
    var valueUnwrapped = ko.unwrap(value);
    // Grab some more data from another binding property
    var duration = allBindings.get('slideDuration') || 400; // 400ms is default duration unless otherwise specified
    // Now manipulate the DOM element
    if (valueUnwrapped == true)
      $(element).slideDown(duration); // Make the element visible
    else
      $(element).slideUp(duration);  // Make the element invisible
  }
}; 

You can then use this custom binding like this:

<div data-bind="slideVisible: giftWrap, slideDuration:600">You have selected the option</div>
<label><input type="checkbox" data-bind="checked: giftWrap" /> Gift wrap</label>
<script type="text/javascript">
  var viewModel = {
    giftWrap: ko.observable(true)
  };
  ko.applyBindings(viewModel);
</script> 

init callback

ko will call your init function for every dom element that uses binding, it has two main purposes:

(1) Set the initialization state for the dom element;

(2) Register some event handlers, for example: when the user clicks or modifies the dom element, you can change the status of the monitoring attribute;

ko will use the exact same set of parameters as the update callback.

Continuing with the previous example, you may want slideVisible to set the visibility state of the element (without any animation effect) when the page is first displayed, and the animation effect is executed when it changes later. You can follow Here’s how to do it:

ko.bindingHandlers.slideVisible = {
  init: function(element, valueAccessor) {
    var value = ko.unwrap(valueAccessor()); // Get the current value of the current property we're bound to
    $(element).toggle(value); // jQuery will hide/show the element depending on whether "value" or true or false
  },
  update: function(element, valueAccessor, allBindings) {
    // Leave as before
  }
}; 

giftWrap is initialized and defined as false (ko.observable(false)). The associated DIV will be hidden during initialization, and then the DIV will be displayed only when the user clicks the checkbox.

You now know how to use update callbacks to update DOM elements when the observable value changes. We can now use another method to do it. For example, when the user performs an action, it can also cause your observable value to be updated, for example:

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();
  }
}; 

Now you can read and write your observable values ​​via the element's "focusedness" binding.

<p>Name: <input data-bind="hasFocus: editingName" /></p>
<!-- Showing that we can both read and write the focus state -->
<div data-bind="visible: editingName">You're editing the name</div>
<button data-bind="enable: !editingName(), click:function() { editingName(true) }">Edit name</button>
<script type="text/javascript">
  var viewModel = {
    editingName: ko.observable()
  };
  ko.applyBindings(viewModel);
</script>

The above content is the method for creating Knockout custom binding shared by the editor. I hope you like it.

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn