zoukankan      html  css  js  c++  java
  • 翻译:Knockout 快速上手

    Utilities

    Knockout 提供了许多可以你开发中使用的工具,你可以在 ko.utils 命名空间中找到它们,我最喜欢的工具如下所示:

    • extend: 这个方法将两个对象合并在一起,调用这个方法之后,会将第二个对象的所有属性,方法合并到第一个对象上。
    • unwrapObservable: 这个方法获取一个属性作为参数,然后返回它的值。比如 Knockout 的 Observable 属性,或者一个简单的属性。这个函数在你希望在运行时获取对象的实际值得时候很有用。
    • 所有的数组工具:Knockout 提供了许多对于数据操作的工具,允许你过滤,映射,或者删除其中的项目。我经常在项目开始的时候,将这些方法附加到ko.observableArray.fn 上。

    下面的代码演示了使用方法。

    // extend usage
    var a = { val: 1 },
    b = { val: 2 };
    
    ko.utils.extend(a, b);
    console.log(a.val); // console: 2
    
    // unwrapObservable usage
    var c = ko.observable(99), d = 98;
    console.log(ko.utils.unwrapObservable(c)); // console: 99
    console.log(ko.utils.unwrapObservable(d)); // console: 98
    
    // array "map" utility function usage
    var arr = [100, 101];
    var mapped = ko.utils.arrayMap(arr, function (item) {
        return item + 50;
    })
    
    console.log(arr); // console: [ 150, 151 ]

    Data-bind statements

    我们一直关注 Knockout 的脚本库,实际上,Knockout 被设计为可以简单地将 JavaScript 对象绑定到 HTML 中。API 使用与 HTML5 兼容的 data-bind 语法。在我们前面的示例中,你可以看到可以简单地将 HTML 元素的属性绑定到 ViewModel 的属性上。data-bind 语法允许使用逗号分隔的绑定定义,下面的示例演示了使用方式。

    <span data-bind="text: myText"></span>
    <div data-bind="visible: isVisible, with: someProp"></div>
    <input data-bind="value: someVal,
        css: {
            'error': !someVal.isValid(),
            'success': someVal.isValid()
        }"/>

    Applying bindings

    applyBindings 是 Knockout 一切工作启动的起点。大多数的示例都演示了将一个 ViewModel 作为参数的使用方式。但是你可以通过第二个参数来指定一个 DOM 对象,Knockout 将只会绑定到这个 DOM 节点及其子节点上。

    多数的应用只有一个 ViewModel ,在调用 applyBinding 的时候,也仅仅传递一个 ViewModel 参数。但是,我创建过许多复杂的应用程序,在一个页面中使用了多个 ViewModel 对象,使用多个 ViewModel 的分别处理提示,设置,还有当前用户的信息等等。在这些情况下,通过限制 Knockout 绑定的节点数量,可以获取性能的优势。如果你仅仅需要更新页面的部分内容,就不要通过 Knockout 绑定到整个页面上。

    Binding handlers

    我曾经提到过 Knockout 提供了许多的扩展点。有一些比 Knockout 的 Binding handler 更方便。虽然通过 data-bind 语法实现了 binding handler 。Knockout 还允许我们自定义绑定的处理器,所以,我们可以实现,或者重写,我们自定义的功能。

    在 MVVM 风格的开发中, 我们会有两种类型的绑定:单向和双向绑定。单向的绑定是简单的信息读取,将 ViewModel 中的数据读取出来绑定到 DOM 中。你可以想像出双向的数据绑定就是在单向的基础之上,将 DOM 对象的更新返回到 ViewModel 的属性上。Knockout 允许我们创建所有类型的绑定,下面的代码演示了基本处理器使用。

    ko.bindingHandlers['myHandler'] = {
        init: function (element, valueAccessor, allBindingsAccessor,  viewModel, bindingContext) {
        },
    
        update: function (element, valueAccessor, allBindingsAccessor,    viewModel, bindingContext) {
    
        }
    };

    如你所见,我们提供了两个钩子来实现我们的逻辑。Init 和 update 函数。这些函数的参数如下所示:

    • element: 定义 data-bind 的元素
    • valueAccessor:返回 ViewModel 绑定属性值得函数。如果绑定到 Observable 属性,那么回返回这个 Observalbe,在我们的处理逻辑中,需要将这个 Observable 进行 upwarp处理。
    • allBindingAccessor:类似于 valueAccessor ,但是它返回一个包含所有绑定和绑定值的对象。
    • viewModel:传递给 applyBindings 的视图模型或者根对象
    • bindingContext:专用的一个特殊对象,包含表示当前绑定上下文环境的特定信息。绑定上下文中有一个 $data 属性表示当前的绑定,这个属性经常与 viewModel 是相同的。还有 $parent 属性和 $parents 属性,表示绑定元素的上级节点。通常在使用 with 的时候才会使用这些属性。

    你可以在想,这些东西看起来都差不多,我们应该在哪里实现我们的业务逻辑呢?init 函数仅仅在调用 applyBinding 的时候调用一次。Knockout 遍历整个 DOM 树,查找 data-bind 语法,处理它们,在每个需要的绑定上,调用 init 方法。然后,在调用 init 方法之后,立即调用 update 方法,以后,在绑定发生变化的时候会多次调用这个方法 ( 如果是 Subscribable )。

    我的处理方式是在 init 中注册我所有的事件处理器 ( change, blur, focus ) ,然后在 update 中处理 HTML。

    下面的代码演示了常见的单向绑定,这个例子与 visible 正好相反,我们可以使用 isHidden 而不是 isVisible。

    // invisible -> the inverse of 'visible'
    ko.bindingHandlers['invisible'] = {
        update: function (element, valueAccessor) {
            var newValueAccessor = function () {
                // just return the opposite of the visible flag!
                return !ko.utils.unwrapObservable(valueAccessor());
            };
    
            return ko.bindingHandlers.visible.update(element,        newValueAccessor);
    
        }
    };

    下面的代码演示了双向的绑定,这个例子演示对一个数字的验证,从元素中获取数据传递到 ViewModel,在 ViewModel 发生变化的时候也可以传递到 DOM。

    // simple number parsing
    function parseNumber(strVal){
        return parseInt(strVal, 10);
    }
    
    // very basic two-way binding handler
    ko.bindingHandlers['number'] = {
        init: function (element, valueAccessor, allBindingsAccessor) {
            //handle the input changing
            ko.utils.registerEventHandler(element, "change", function () {
                var observable = valueAccessor();
                var number = parseNumber(element.value);
                if (number !== NaN) {
                    observable(element.value);
                }
            });
        },
    
        update: function (element, valueAccessor) {
            var value = ko.utils.unwrapObservable(valueAccessor());
            var number = parseNumber(value);
            if (number !== NaN) {
                element.setAttribute("value", number);
            }
        }
    };

    Summary

    你可以看到 Knockout 是一个非常成熟的脚本库,在这一节我们学到下面的内容:

    • Knockout 的核心对象和使用方式
    • Knockout 的实用工具
    • 如何创建和管理多个的 ViewModel
    • 定制绑定处理器
  • 相关阅读:
    JCTF 2014(Reverse)
    JCTF 2014(Misc)
    实验吧CTF题库-密码学(部分)
    第四章 Jinja2模版
    第三章 URL与视图
    flask学习导航主页
    flask调试模式
    rontab踩坑(三):crontab定时任务调度机制与系统时间/时区的不一致
    crontab踩坑(二):Unit crond.service could not be found.
    crontab踩坑(一)
  • 原文地址:https://www.cnblogs.com/haogj/p/3446736.html
Copyright © 2011-2022 走看看