zoukankan      html  css  js  c++  java
  • Knockout应用开发指南 第五章:创建自定义绑定

    创建自定义绑定

    你可以创建自己的自定义绑定 – 没有必要非要使用内嵌的绑定(像click,value等)。你可以你封装复杂的逻辑或行为,自定义很容易使用和重用的绑定。例如,你可以在form表单里自定义像grid,tabset等这样的绑定。

    重要:以下文档只应用在Knockout 1.1.1和更高版本,Knockout 1.1.0和以前的版本在注册API上是不同的。

    注册你的绑定

    添加子属性到ko.bindingHandlers来注册你的绑定:

    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.
    }
    };

    … 然后就可以在任何DOM元素上使用了:

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

    注:你实际上没必要把init和update这两个callbacks都定义,你可以只定义其中的任意一个。

    update 回调

    当管理的observable改变的时候,KO会调用你的update callback函数,然后传递以下参数:

    • element — 使用这个绑定的DOM元素
    • valueAccessor —JavaScript函数,通过valueAccessor()可以得到应用到这个绑定的model上的当前属性值。
    • allBindingsAccessor —JavaScript函数,通过allBindingsAccessor ()得到这个元素上所有model的属性值。
    • viewModel — 传递给ko.applyBindings使用的 view model参数,如果是模板内部的话,那这个参数就是传递给该模板的数据。

    例如,你可能想通过 visible绑定来控制一个元素的可见性,但是你想让该元素在隐藏或者显示的时候加入动画效果。那你可以自定义自己的绑定来调用jQuery的slideUp/slideDown 函数:

    ko.bindingHandlers.slideVisible = {
    update: function(element, valueAccessor, allBindingsAccessor) {
    // First get the latest data that we're bound to
    var value = valueAccessor(), allBindings = allBindingsAccessor();

    // Next, whether or not the supplied model property is observable, get its current value
    var valueUnwrapped = ko.utils.unwrapObservable(value);

    // Grab some more data from another binding property
    var duration = allBindings.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
    }
    };



    然后你可以像这样使用你的绑定:

    <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 回调

    Knockout在DOM元素使用自定义绑定的时候会调用你的init函数。init有两个重要的用途:

    • 为DOM元素设置初始值
    • 注册事件句柄,例如当用户点击或者编辑DOM元素的时候,你可以改变相关的observable值的状态。

     KO会传递和update回调函数一样的参数。

    继续上面的例子,你可以像让slideVisible在页面第一次显示的时候设置该元素的状态(但是不使用任何动画效果),而只是让动画在以后改变的时候再执行。你可以这样来做:

    ko.bindingHandlers.slideVisible = {
    init: function(element, valueAccessor) {
    var value = ko.utils.unwrapObservable(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, allBindingsAccessor) {
    // Leave as before
    }
    };

    这就是说giftWrap的初始值声明的是false(例如giftWrap: ko.observable(false)),然后让初始值会让关联的DIV隐藏,之后用户点击checkbox的时候会让元素显示出来。

    DOM事件之后更新observable值

    你已经值得了如何使用update回调,当observable值改变的时候,你可以更新相关的DOM元素。但是其它形式的事件怎么做呢?比如当用户对某个DOM元素有某些action操作的时候,你想更新相关的observable值。

    你可以使用init回调来注册一个事件句柄,这样可以改变相关的observable值,例如,

    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.utils.unwrapObservable(value))
    element.focus();
    else
    element.blur();
    }
    };

    现在你可以通过hasFocus绑定来读取或者写入这个observable值了:

    <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>



     

  • 相关阅读:
    loj#6433. 「PKUSC2018」最大前缀和(状压dp)
    PKUWC2019游记
    10. Regular Expression Matching
    9. Palindrome Number
    8. String to Integer (atoi)
    7. Reverse Integer
    6. ZigZag Conversion
    5. Longest Palindromic Substring
    4. Median of Two Sorted Arrays
    3. Longest Substring Without Repeating Characters
  • 原文地址:https://www.cnblogs.com/TomXu/p/2256949.html
Copyright © 2011-2022 走看看