zoukankan      html  css  js  c++  java
  • KnockoutJS 3.X API 第五章 高级应用(1) 创建自定义绑定

    您不仅限于使用内置的绑定,如click,value绑定等,您可以创建自己的绑定。 这是如何控制视图模型如何与DOM元素进行交互,并且为您提供了大量的灵活性,以便于以复用的方式封装复杂的行为。

    注册绑定

    要注册绑定,请将其作为ko.bindingHandlers的子属性添加,比如如下例子:

    ko.bindingHandlers.yourBindingName = {
        init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
            // 这是首次运行绑定的初始化回调函数
            // 在此处设置初始状态和事件处理程序
        },
        update: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
            // 当绑定首次应用到元素时,将调用一次
            // 每当监控属性/计算属性的值发生变化时
            // 每当DOM绑定的元素值方法变化时被调用.
        }
    };

    然后你可以使用它在任何数量的DOM元素:

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

    注意:你实际上不必提供完整的init和update回调 - 你可以只提供一个或另一个。

    ‘update’回调函数

    当绑定应用于元素并跟踪您访问的任何依赖性(observables / computeds)时,Knockout将最初调用update回调。 当任何这些依赖关系改变时,将再次调用update回调。 将以下参数传递给它:

    • element — 此绑定中涉及的DOM元素
    • valueAccessor — 可以调用的JavaScript函数,以获取此绑定中涉及的当前模型属性。 调用此函数而不传递任何参数(即调用valueAccessor())以获取当前模型属性值。 要容易接受observable和plain值,请对返回的值调用ko.unwrap。
    • allBindings —可用于访问绑定到此DOM元素的所有模型值的JavaScript对象。 调用allBindings.get('name')检索名称绑定的值(如果绑定不存在则返回undefined); 或allBindings.has('name')来确定当前元素是否存在名称绑定。
    • viewModel — 此参数在Knockout 3.x中已弃用。 使用bindingContext。$ data或bindingContext $ raw用于访问视图模型的数据。
    • bindingContext — 保存可用于此元素的绑定的绑定上下文的对象。 此对象包括特殊属性,包括$ parent,$ parents和$ root,可用于访问与此上下文的祖先绑定的数据。

    例如,您可能已经使用可见绑定控制元素的可见性,但现在您想要进一步进行和动画转换。 您希望元素根据observable的值滑入和滑出存在。 你可以通过编写调用jQuery的slideUp / slideDown函数的自定义绑定来实现:

    You have selected the option

    源码:

    <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.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
            }
        };
        ko.applyBindings(viewModel);
    </script>

    当然,乍一看很多的代码,但一旦你创建了你的自定义绑定,他们可以很容易地重用在许多地方。

    ‘init’回调函数

    Knockout将为您使用绑定的每个DOM元素调用一次init函数。 init有两个主要用途:

    • 为DOM元素设置初始状态
    • 注册任何事件处理程序,例如,当用户单击或修改DOM元素时,可以更改关联的可观察事件的状态

    KO将传递给init的参数和update回调具有完全相同的参数集。

    继续前面的示例,您可能希望使用slideVisible将元素设置为在页面第一次出现时立即可见或不可见(没有任何动画幻灯片),以便动画只在用户更改模型状态时运行。 你可以这样做:

    You have selected the option

    源码:

    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被定义为初始状态为false(即,giftWrap:ko.observable(false)),则相关联的DIV最初将被隐藏,然后当用户稍后检查该框时滑入视图。

    在DOM事件后修改observable

    您已经了解如何使用udpate,以便在监控属性的更改时,可以更新关联的DOM元素。 但是在另一个方向的事件呢? 当用户对DOM元素执行某些操作时,您可能需要更新关联的监控属性。

    您可以使用init回调作为注册事件处理程序的地方,这将对关联的observable进行更改。 例如

    Name:

    You're editing the name

    源码:

    <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.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();
            }
        };
        ko.applyBindings(viewModel,document.getElementById('eq3'));
    </script>

    现在,您可以通过将元素绑定到可监控对象来读取和写入元素的“焦点”。

    备注,虚拟绑定

    如果您希望自定义绑定可用于Knockout虚拟元素语法,可使用如下写法:

    <!-- ko mybinding: somedata --> ... <!-- /ko -->
  • 相关阅读:
    asp.net HttpModule和HttpHandler
    Asp.Net生命周期和Http管道技术
    降低web服务器压力
    html里嵌入CSS的三种方式
    php实现简单视图模板(视图引擎)
    ASP.NET MVC路由配置
    igel udc2 config
    单IP、网络、别名管道限速的设置
    Apple SIP简介及在Clover中如何控制
    Hackintosh
  • 原文地址:https://www.cnblogs.com/smallprogram/p/5959262.html
Copyright © 2011-2022 走看看