Knockout.js(四):自定义绑定

  除了内嵌的绑定,还可以创建一些自定义绑定,封装复杂的逻辑或行为。

  

  注册绑定

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

ko.bindingHandlers.yourBindingName = {
    init: function(element, valueAccessor, allBindingsAccessor, viewModel) {
        // 第一次应用于元素时调用,在这里设置任何初始状态,事件处理程序等
    },

    update: function(element, valueAccessor, allBindingsAccessor, viewModel) {
        // 当绑定首先应用于元素时,将被调用一次,并且每当相关联的observable更改值时,都会被调用一次。并根据这里提供的值更新DOM元素。
    }
};

  然后在DOM元素上调用:

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

  init和update这两个函数不是必须都定义,也可以只定义其中一个。

  当管理的observable改变的时候,KO会调用回调函数,传递一下参数:

  ♦ element:使用这个绑定的DOM元素

  ♦ valueAccessor:JavaScript函数,通过valueAccessor()可以得到应用到这个绑定的model上的当前属性值。

  ♦ allBindingsAccessor:JavaScript函数,通过allBindingsAccessor ()得到这个元素上所有model的属性值。

  ♦ viewModel :传递给ko.applyBindings使用的 view model参数,如果是模板内部的话,那这个参数就是传递给该模板的数据。

  init回调

  Knockout在DOM元素使用自定义绑定的时候会调用init函数。init的用途:

  ♦ 为DOM元素设置初始值

  ♦ 注册事件handle,例如当用户点击或者编辑DOM元素的时候,可以改变相关的的observable值的状态。

  可以在页面第一次显示的时候设置该元素的状态(但是不使用任何动画效果),而只是让动画在以后改变的时候再执行。

ko.bindingHandlers.hideControl= {
    init: function(element, valueAccessor, allBindingsAccessor,viewModel) {
        var flag = localStorage.flag;
        // 获取本地存储中的flag值
        if(flag == 1){
            $(element).hide();
        }
    },
    update: function(element, valueAccessor, allBindingsAccessor,viewModel) {
    }
};

  update回调

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

ko.bindingHandlers.slideVisible = {
    update: function(element, valueAccessor, allBindingsAccessor) {
        // 首先获取最新的绑定值
        var value = valueAccessor(), allBindings = allBindingsAccessor();        

        // 不管所提供的模型属性是否可观察到,获取其当前值
        var valueUnwrapped = ko.utils.unwrapObservable(value);

        // 从另一个绑定属性中获取更多数据,除非另有说明,否则默认为400ms
        var duration = allBindings.slideDuration || 400;
     
        // 操作DOM元素
        if (valueUnwrapped == true)
            $(element).slideDown(duration);
        else
            $(element).slideUp(duration);
    }
};

  其他形式的事件

  知道了如何使用update回调,当obeservable值改变的时候,可以更新相关的DOM元素,对于其他形式的事件(如用户点击某个element的事件)想要更新相关的observable值。

  可以使用init回调来注册一个事件handle,这样可以改变相关的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();
    }
};

  在DOM上调用

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

  绑定viewModel

<script type="text/javascript">
    var viewModel = {
        editingName: ko.observable()
    };
    ko.applyBindings(viewModel);
</script>
原文地址:https://www.cnblogs.com/weilan/p/7612389.html