zoukankan      html  css  js  c++  java
  • 初学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});
  • 相关阅读:
    第一节:SpringMVC概述
    SpringMVC【目录】
    Windows 系统快速查看文件MD5
    (error) ERR wrong number of arguments for 'hmset' command
    hive使用遇到的问题 cannot recognize input
    Overleaf支持的部分中文字体预览
    Understanding and Improving Fast Adversarial Training
    Django2实战示例 第十三章 上线
    Django2实战示例 第十二章 创建API
    Django2实战示例 第十一章 渲染和缓存课程内容
  • 原文地址:https://www.cnblogs.com/petunsecn/p/4886773.html
Copyright © 2011-2022 走看看