Knockout 计算属性

Posted tangge

tags:

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

Computed

首先,创建一个view model如下:

<body>
    <p>The fullname is: <span data-bind="text: fullName"></span></p>
  </body>

  <script>
    function MyViewModel() {
      this.firstName = ko.observable("Chiaki");
      this.lastName = ko.observable("Izumi");
      this.fullName = ko.computed(function() {
        return this.firstName() + " " + this.lastName();
      }, this);
    }

    ko.applyBindings(new MyViewModel());
  </script>

技术分享图片
每当firstName或是lastName中至少一个变化的时候,就会调用一次ko.computed来生成fullName并反映在UI中。

从以上示例中也可以看到,ko.computed有两个参数,第一个是联系两个observable并生成fullName的函数,第二个是this。第二个参数指定了第一个参数中的this的值(这个看起来的确有些怪异,可以留作以后研究),按照文档中的说法,javascript中的函数在默认情况下并不是object的一部分,所以需要指定this的值。

也有一种通用的简化方式,即将this在构造函数一开始就赋给另一个变量,这样在之后需要用到this的部分即可以通过调用另一个变量来实现:

function MyViewModel() {
  var self = this;

  self.firstName = ko.observable("Chiaki");
  self.lastName = ko.observable("Izumi");
  self.fullName = ko.computed(function() {
    return self.firstName()+ " " + self.lastName();
  });
}

个人分析,之所以能够通过这种方式来简化,跟javascript中的this机制有关,可能在javascript中每当遇到一个this的时候就分析当前的object到底是哪个,进而对this进行替代,但是进入到ko.computed函数里面之后,由于函数并不算是object的一部分,this的值也就不再是当前的object(MyViewModel),而变成了window,使用self以后就涉及到闭包的问题了,使得self的值并不会更改,这个可以留作以后研究。

如果computed observable知识基于一些observable的简单计算的话,使用pureComputed会比computed更好,如下:

self.fullName = ko.pureComputed(function() {
   return self.firstName()+ " " + self.lastName();
 })

我们也可以对computed或是pureComputed进行强制订阅,如下:

this.fullName = ko.pureComputed(function() {
        return this.firstName() + " " + this.lastName();
      }, this).extend({notify: "always"});

同样的,可以通过调用extend方法中的rateLimit属性来指定响应的延时。

在某些时候,我们可能需要判定某个变量到底是不是computed observable,这时可以用到ko.isComputed来进行判断,类似的方法还包括isObservablem,isWritableObservable等,其中isObservable对于observables、observable arrays、computed observables均会返回true;isWritableObservable对于observables、observable arrays、writable computed observables均会返回true,这部分可以留作以后研究。

参考:

官网,computedObservables
CharlieYuki,KnockoutJs学习笔记(三),Using computed observables

PureComputed

Pure computed observables相对于一般的computed observables,在性能和存储上有优势,这是因为pure computed observables在不存在订阅者的时候是不会保持订阅关系的。这也使得pure computed observables有如下两点特点:

  • 可以防止没有被订阅的computed observables的存储泄露。
  • 可以降低因重复计算未被订阅的computed observables而造成的运算过载。

一个pure computed observable能够依据它是否拥有订阅者而自动地在两种状态下切换:
1.当不存在订阅者的时候,pure computed observable会进入休眠状态,此时的它,会关闭所有依赖于它的订阅关系,同时也不会再追踪它所关联的observables。一旦处于休眠状态的computed observable的值被读取的话,它就需要重新计算以便以确保值得正确性。
2.当它拥有订阅者的时候,pure computed observable会进入监听状态。一旦进入监听状态,它会立即调用它的function和订阅程序来追踪它所关联的observables。在这种状态下,pure computed observables和普通的computed observables无异。更为详细的内容需参考How dependency tracking works部分。

按照文档的说明,选择pure computed observables有两条原则。一是computed observable在运算的时候不能产生副作用(不能对其他的observables产生影响);二是computed observable的值应该仅仅依赖于它所关联的observables的值,而不是其他隐含的信息。

Pure computed observables有两种定义方式:

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

或者

this.fullName = ko.computed(function() {
    return this.firstName() + " " + this.lastName();
}, this, { pure: true });

参考:

官网,Pure computed observables

以上是关于Knockout 计算属性的主要内容,如果未能解决你的问题,请参考以下文章

Knockout计算列与模型

Knockout.js 获取 location.href 对象的属性

Knockout.js:当可观察数组中的值发生变化时触发计算的最佳方法是啥

Visual Studio 数据绑定属性突出显示 [knockout.js]

循环遍历具有可观察属性的 Knockout 可观察对象数组

使用 Vue 模板清晰地分离视图和代码