(初)Knockout 监控属性(Observables)

Posted tangge

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了(初)Knockout 监控属性(Observables)相关的知识,希望对你有一定的参考价值。

1 创建带有监控属性的view model

1.1 Observables

Knockout是在下面三个核心功能是建立起来的:

  • 监控属性(Observables)和依赖跟踪(Dependency tracking)
  • 声明式绑定(Declarative bindings)
  • 模板(Templating)

MVVM and View Models

Model-View-View Model (MVVM) 是一种创建用户界面的设计模式。 描述的是如何将复杂的UI用户界面分成3个部分:

  • model: 你程序里存储的数据。这个数据包括对象和业务操作(例如:银子账户可以完成转账功能), 并且独立于任何UI。使用KO的时候,通常说是向服务器调用Ajax读写这个存储的模型数据。
  • view model: 在UI上,纯code描述的数据以及操作。例如,如果你实现列表编辑,你的view model应该是一个包含列表项items的对象和暴露的add/remove列表项(item)的操作方法。

    注意这不是UI本身:它不包含任何按钮的概念或者显示风格。它也不是持续数据模型 – 包含用户正在使用的未保存数据。使用KO的时候,你的view models是不包含任何html知识的纯javascript 对象。保持view model抽象可以保持简单,以便你能管理更复杂的行为。

  • view: 一个可见的,交互式的,表示view model状态的UI。 从view model显示数据,发送命令到view model(例如:当用户click按钮的时候) ,任何view model状态改变的时候更新。

使用KO的时候,你的view就是你带有绑定信息的HTML文档,这些声明式的绑定管理到你的view model上。或者你可以使用模板从你的view model获取数据生成HTML。

创建一个view model,只需要声明任意的JavaScript object。例如:

var myViewModel = {
    personName: 'Bob',
    personAge: 123
};

你可以为view model创建一个声明式绑定的简单view。例如:下面的代码显示personName 值:

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

Activating Knockout

data-bind属性尽快好用但它不是HTML的原生属性(它严格遵从HTML5语法, 虽然HTML4验证器提示有不可识别的属性但依然可用)。由于浏览器不识别它是什么意思,所以你需要激活Knockout 来让他起作用。

激活Knockout,需要添加如下的 <script> 代码块:

ko.applyBindings(myViewModel);

你可以将这个代码块放在HTML底部,或者放在jQuery的$函数或者ready 函数里,然后放在页面上面, 最终生成结果就是如下的HTML代码:

The name is <span>Bob</span>

你可能奇怪ko.applyBindings使用的是什么样的参数,

  • 第一个参数是你想用于声明式绑定
  • 第二个参数(可选),可以声明成使用data-bind的HTML元素或者容器。例如, ko.applyBindings(myViewModel, document.getElementById(‘someElementId‘))。它的现在是只有作为someElementId 的元素和子元素才能激活KO功能。 好处是你可以在同一个页面声明多个view model,用来区分区域。

Observables

现在已经知道如何创建一个简单的view model并且通过binding显示它的属性了。但是KO一个重要的功能是当你的view model改变的时候能自动更新你的界面。当你的view model部分改变的时候KO是如何知道的呢?答案是:你需要将你的model属性声明成observable的, 因为它是非常特殊的JavaScript objects,能够通知订阅者它的改变以及自动探测到相关的依赖。

例如:将上述例子的view model改成如下代码:

var myViewModel = {
    personName: ko.observable('Bob'),
    personAge: ko.observable(123)
};

你根本不需要修改view – 所有的data-bind语法依然工作,不同的是他能监控到变化,当值改变时,view会自动更新。

监控属性(observables)的读和写

不是所有的浏览器都支持JavaScript的 getters and setters (比如IE),,所以为了兼容性,使用ko.observable监控的对象都是真实的function函数。

  • 读取监控属性(observable)的值,只需要直接调用监控属性(observable)(不需要参数),例如myViewModel.personName() 将返回‘Bob‘, myViewModel.personAge() 将返回 123。
  • 写一个新值到监控属性(observable)上,调用这个observable属性并当新值作为参数。例如:调用 myViewModel.personName(‘Mary‘) 将更新name值为‘Mary‘。
  • 给一个model对象的多个属性写入新值,你可以使用链式语法。例如: myViewModel.personName(‘Mary‘).personAge(50) 将会将name更新为 ‘Mary‘ 并且 将age更新为 50.
    监控属性(observables)的特征就是监控(observed),例如其它代码可以说我需要得到对象变化的通知,所以KO内部有很多内置的绑定语法。所以如果你的代码写成data-bind="text: personName", text绑定注册到自身,一旦personName的值改变,它就能得到通知。

当然调用myViewModel.personName(‘Mary‘)改变name的值,text绑定将自动更新这个新值到相应的DOM元素上。这就是如何将view model的改变传播到view上的。

监控属性(Observables)的显式订阅

通常情况下,你不用手工订阅,所以新手可以忽略此小节。高级用户,如果你要注册自己的订阅到监控属性(observables),你可以调用它的subscribe 函数。例如:

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

这个subscribe 函数在内部很多地方都用到的。你也可以终止自己的订阅:首先得到你的订阅,然后调用这个对象的dispose函数,例如:

var subscription = myViewModel.personName.subscribe(function (newValue) { /* do stuff */ });
// ...then later...
subscription.dispose(); // I no longer want notifications

大多数情况下,你不需要做这些,因为内置的绑定和模板系统已经帮你做好很多事情了,可以直接使用它们。

2 使用依赖监控属性(Dependent Observables)

如果你已经有了监控属性firstName和lastName,你想显示全称怎么办? 这就需要用到依赖监控属性了 – 这些函数是一个或多个监控属性, 如果他们的依赖对象改变,他们会自动跟着改变。

例如,下面的view model,

var viewModel = {
    firstName: ko.observable('Bob'),
    lastName: ko.observable('Smith')
};

… 你可以添加一个依赖监控属性来返回姓名全称:

viewModel.fullName = ko.dependentObservable(function () {
    return this.firstName() + " " + this.lastName();
}, viewModel);

并且绑定到UI的元素上,例如:

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

完整代码:

  <body>
    <!-- text 绑定注册到自身 -->
    The name is <span data-bind="text: fullName"></span>
  </body>
  <script src="../js/knockout-3.5.0rc2.debug.js"></script>
  <script>
    var viewModel = {
      firstName: ko.observable("Bob"),
      lastName: ko.observable("Smith")
    };

    // 依赖监控属性(Dependent Observables)
    // 这些函数是一个或多个监控属性, 如果他们的依赖对象改变,他们会自动跟着改变。
    //computed == dependentObservable
    viewModel.fullName = ko.dependentObservable(function() {
      return this.firstName() + " " + this.lastName();
    }, viewModel);

    ko.applyBindings(viewModel);
  </script>

技术图片

以上是关于(初)Knockout 监控属性(Observables)的主要内容,如果未能解决你的问题,请参考以下文章

knockout 简单使用

knockout学习资料

Knockout学习笔记--使用计算属性

knockout.js

knockout.js

Knockout.js简介