• 初学knockoutjs记录2——Observables监控属性(1 创建带有监控属性的view model)


    1、knockout建有3个核心特性:

      Observables监控属性和dependency tracking依赖跟踪

      Declarative bindings 声明式绑定

      Templating 模板

    2、MVVM and View Models

      Model-View-View Model(MVVM) 是为了解决用户交互构建的设计模式,它通常被描述为如何将复杂的UI交互简单的分为三个部分:

      A Model: 应用程序的stored data存储数据模型,包含业务领域的对象和操作,并且是独立于UI的,当使用KO时,通常会使用Ajax调用服务端代码去读写这个存储数据模型。

      A view model: 纯code表达的UI上的数据和操作,例如你实现一个列表编辑,你的view model通常是一个包含列表项的对象,以及公开出来的添加或移除列表项的方法;注意这个并不是UI本身,它并不包含任何按钮或者显示样式的东西,它也不是持久数据模型,它拥有的是用户使用着的不保存的数据,当使用KO时,你的view model是不包含HTML相关概念的纯javascript对象,保持view model的抽象可以使其保持简单,以便你能够管理更复杂的行为而不至于迷失。

      A view: 可见的,交互式的呈现view model状态的UI,它呈现view model的信息,发送命令到view model,并且在view model有任何变化时更新它的状态,当使用KO时,你的view无非就是以声明式绑定方式绑定到view model的HTML文档,或者,你也可以使用模板基于你view model中的数据生成HTML。

      使用KO创建view model的方式如下,就像声明任何javascript对象一样

    var helloViewModel = {
            personName: "Bob",
            age: 123
        };

      接下来可以使用声明式绑定方式为这个view model创建一个非常简单的view,例如创建一个显示personName的标签

    The name is <span data-bind="text: personName"></span>

      Activating knockout

        data-bind尽管很棒但是它并不是HTML原生属性(它严格遵从HTML5语法,尽管HTML4的验证器会提示有不可识别的属性但是使用它并不会有问题),但是因为浏览器并不认识它,所以需要激活knockout以便使其生效。

        激活knockout使用如下的代码块

    ko.applyBindings(helloViewModel);

        你可以将这个script代码块放在HTML文档的底部,也可以将其放在页面上边并且同时将其包含在ready处理函数中,比如jQuery的$函数中。现在你的view将如同写了如下的HTML代码一样的呈现出来

    The name is <span>Bob</span>

        ko.applyBindings的参数:

          第一个参数是想要用声明式绑定激活的view model,

          第二个参数是可选的,用来指定你想要绑定页面的那些部分,例如ko.applyBindings(helloViewModel, document.getElementById('specialElementId')),它约束了可以激活specialElementId的元素及其子元素,这样的好处是可以有多个view model以对应页面的多个区域。

    3、Observables

      现在你已经知道了怎样创建一个基本的view model并且使用binding显示它的一个属性,然而KO的一个重要的特性是它能够在view model变化时自动的更新画面。KO怎么知道你的view model变化了呢?答案是:你需要将你的model声明成observables的,因为它是一个特殊的javascript对象,能够将变化通知给订阅者,并且能够自动检测依赖。

      像下边这样重写之前的view model

    var helloViewModel = {
        personName: ko.observable("Bob"),
        age: ko.observable(123)
    }

      你完全不需要改变之前的view,同样的data-bind语法仍然工作,不同的是,它现在能够检测到变化,并且当变化发生时自动的更新view.

      Reading and writing observables 监控属性的读和写

        不是所有的浏览器都支持javascript的getters和setters(比如IE),所以,为了兼容性,ko.observable监控的对象实际上是函数

        读取监控属性(observable)当前的值,只需要调用监控属性,不需要参数。在这个例子中,helloViewModel.personName()将返回“Bob”,helloViewModel.age将返回123.

        写入新值到监控属性(observable)上,调用监控属性,并将新的值作为参数传递给它。例如,调用helloViewModel.personName("Mary")将把姓氏更新成Wang.

        写入新值到一个model对象的多个监控属性,你可以使用链式语法。例如,helloViewModel.personName("Mary").age("50")将把名字改为Mary,并把年龄改为50

        监控属性整个的意义就是它可以被监控,也就是其它的代码可以说它想要得到变化的通知,这就是KO内部会有很多的内置绑定。因此,当你写了data-bind="text:personName", 就会将text的绑定注册到它自身以便当personName变化时得到通知(假设它就像现在这样是可监控的)。

        当你使用helloViewModel.personName("Mary")来将名字改为“Mary”时,text的绑定将自动更新对应的DOM元素的文本内容,这就是如何将view model的改变自动的传递到view上。

      

      Explicitly subscribing to observables 监控属性的显示订阅

        对于高级用户来说,如果你需要注册自己的订阅到监控属性的更新通知,你可以调用它们的subscribe函数,例如

    myViewModel.personName.subscribe(function(newValue)){
      alert("The person's new name is " + newValue);  
    }

        KO内部工作时使用了大量的subscribe函数调用,大多数时候你不需要用到它,因为内置绑定和模板系统会管理订阅。

        subscribe函数接受3个参数: "callback" 是任何时候通知发生时被调用的函数(理解成回调); "tatget"定义callback函数的中this的值,这个参数是可选的;“event”,可选的,默认值为“change”,是接收到的事件名称

        你也可以在你需要的时候终止订阅,首先获取到你的订阅,然后调用的它的dispose函数,例如以下代码:

    var subscription = myViewModel.personName.subscribe(function(newValue)){
    //do something
    });
    // ....
    subscription.dispose();

        如果你想在监控属性的值变化之前收到通知,你可以订阅beforeChange事件,例如:

    myViewModel.personName.subscribe(dunction(oldValue){
        alert("The person's previous name is " + oldValue);
    }, null, "beforeChange");

        注意,KO不保证beforeChange和Change事件能够成对触发,因为可以用代码单独触发其中任何一个事件,如果你需要跟踪一个监控属性的旧值,那么你最好使用订阅去检测和跟踪它。

      Forcing observables to always notify subscribers 监控属性的强制通知

        当向一个监控属性中写入基本类型的值时(如数字,字符,布尔值或null), 监控属性的依赖通常情况只有在值真正改变才会被通知。然后,通过使用内置的通知扩展(notify extender)可以确保监控属性在写入值时它的订阅一定得到通知,即使写入的值和旧值时一样的,你可以如下这样使用该扩展:

    myViewModel.personName.extend({ notify: 'always' });

      

      

      Delaying and/or suppressing change notifications 通知的延迟触发

        一般情况下,监控属性一旦变化,它会立刻通知它的订阅,但是如果是一个变化频繁且代价昂贵的监控属性,为了更好的性能你可以限制或者延迟监控属性的变化通知,下边的例子使用了 rateLimit 扩展, 确保personName的变化每50毫秒最多被通知1次:

    // Ensure it notifies about changes no more than once per 50-millisencond period
    myViewModel.personName.extend({rateLimit:50});
  • 相关阅读:
    深入c#的String类
    C#语法快速热身
    【BZOJ】1676: [Usaco2005 Feb]Feed Accounting 饲料计算
    【BZOJ】2056: gift? 高精度?
    【BZOJ】3036: 绿豆蛙的归宿
    【BZOJ】2321: [BeiJing2011集训]星器
    【VIJOS】P1401复制CS
    【BZOJ】2453: 维护队列&&【BZOJ】2120: 数颜色 二分+分块 双倍经验
    【BZOJ】3343: 教主的魔法
    【BZOJ】1452: [JSOI2009]Count 树状数组
  • 原文地址:https://www.cnblogs.com/petunsecn/p/4886773.html
Copyright © 2020-2023  润新知