4.纯计算属性

纯计算监控在KO 3.2.0中开始引入,比大多数应用程序使计算监控有更大的性能提升和内存优化。这是因为在自身没有订阅的时候不会保持订阅状态。特性如下

  • 阻止内存泄露 - 避免在应用程序里计算监控不再被引用但是依赖仍然存在。
  • 减少计算开销 - 当值不再被监控不会重新计算计算监控的值。

纯计算监控会在两个状态之间自动切换,基于它是否改变了订阅者。

  1. 当订阅者没有发生改变,它会休眠。当进入休眠状态,它释放所有自身依赖的订阅。在这种状态下,它不会订阅访问求值函数里面的的监控对象(尽管它会继续跟踪它们)。在休眠的时候计算监控的值被读取,如果依赖对象有发生改变,它会自动重新求值。
  2. 当订阅者发生任何改变。它会苏醒并开始监听。处于监听状态,它会马上订阅所有依赖。在这种状态下,它就像计算监控一样工作。

什么是"纯"函数?

(该概念属于函数式编程)

我们参考了pure函数的术语,因为这个特性仅可以应用与计算监控,求值程序的纯功能描述如下 :

  1. 对计算监控求值不会引起任何其他影响。
  2. 计算监控的值不应该受求值规模或其他隐藏信息导致变化。它的值应该仅仅受程序里面其他监控对象的值导致变化,对于纯函数的定义,都考虑了它的参数

语法

定义一个纯计算监控的标准方法是使用ko.purecomputed

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

或者你可以使用ko.computedpure选项:

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

1. 什么情况下使用纯计算监控

你可以在任何计算监控上使用pure特性。你会看到大部分的好处,尽管当它被应用到应用程序设计时,会使用到持久视图模型和共享临时视图和视图模型。在持久视图模型下使用纯计算监控会提供更好的计算性能。在临时视图模型下使用纯计算监控会提供更好的内存管理。

在下面这个简单的导航界面的例子中,纯计算监控属性fullName仅仅在最后一个步骤激活的时候会刷新视图内容。

视图

<div class="log" data-bind="text: computedLog"></div>
<!--ko if: step() == 0-->
<p>First name: <input data-bind="textInput: firstName" /></p>
<!--/ko-->
<!--ko if: step() == 1-->
<p>Last name: <input data-bind="textInput: lastName" /></p>
<!--/ko-->
<!--ko if: step() == 2-->
<div>Prefix: <select data-bind="value: prefix, options: ['Mr.', 'Ms.','Mrs.','Dr.']"></select></div>
<h2>Hello, <span data-bind="text: fullName"> </span>!</h2>
<!--/ko-->
<p><button type="button" data-bind="click: next">Next</button></p>

视图模型

function AppData() {
this.firstName = ko.observable('John');
this.lastName = ko.observable('Burns');
this.prefix = ko.observable('Dr.');
this.computedLog = ko.observable('Log: ');
this.fullName = ko.pureComputed(function () {
var value = this.prefix() + " " + this.firstName() + " " + this.lastName();
//通常情况下,你应该避免在一个纯计算监控里面对一个监控对象赋值(避免副作用)。但是这个例子是为了说明其内部工作原理,输出日志是一种很好的说明方式
this.computedLog(this.computedLog.peek() + value + '; ');
return value;
}, this); this.step = ko.observable(0);
this.next = function () {
this.step(this.step() === 2 ? 0 : this.step()+1);
};
};
ko.applyBindings(new AppData());

2. 什么情况下使用纯计算监控

副作用

在依赖项发生改变的时候需要执行一个操作的时候不应该使用计算监控的pure特性。如例子所示:

  • 基于多个监控的一个计算监控执行一个回调函数
ko.computed(function () {
var cleanData = ko.toJS(this);
myDataClient.update(cleanData);
}, this);
  • 在绑定的初始化函数,使用计算监控更新绑定元素值。
ko.computed({
read: function () {
element.title = ko.unwrap(valueAccessor());
},
disposeWhenNodeIsRemoved: element
});

你不应该使用纯计算监控的原因是如果求值函数很容易引起严重的副作用,副作用就是无论何时计算未激活订阅(也就是休眠状态),求值函数就不会执行。当依赖改变,求值函数就必须执行,请使用计算监控。

3. 确定一个属性是否上纯计算监控

在某些场景,如果你用纯计算监控处理问题,通过程序确定某个属性是否是纯计算监控是很有用的。KO提供了一个工具函数,ko.isPureComputed能处理这个问题。比如,您可能希望从返回服务器的数据中排除非纯计算监控值。

var result = {};
ko.utils.objectForEach(myObject, function (name, value) {
if (!ko.isComputed(value) || ko.isPureComputed(value)) {
result[name] = value;
}
});

4. 状态改变通知

当纯计算监控进入监听状态,它会通知awake事件(使用其当前值),当它进入睡眠状态,它会通知一个asleep事件(使用undefined值)。一般情况下,你不需要知道计算监控内部的状态。但是内部状态可以反应出计算监控是否绑定到了视图,你可能会利用那个状态信息做一些视图模型初始化或清理。

this.someComputedThatWillBeBound = ko.pureComputed(function () {
...
}, this); this.someComputedThatWillBeBound.subscribe(function () {
// do something when this is bound
}, this, "awake"); this.someComputedThatWillBeBound.subscribe(function () {
// do something when this is un-bound
}, this, "asleep");

awake事件在一般的计算监控用deferEvaluation选项创建的时候也会响应。

Knockout v3.4.0 中文版教程-8-计算监控-纯计算属性的更多相关文章

  1. Knockout v3.4.0 中文版教程-5-计算监控-使用计算监控

    3. 计算监控 1.使用计算监控 如果你有一个监控的属性firstName和另一个lastName,但你想显示全名怎么办? 这就是引入计算监控的原因-这是依赖于一个或多个其他的observables函 ...

  2. Knockout v3.4.0 中文版教程-9-计算监控-API参考

    5.参考 下面的内容描述了如何构建和使用计算监控. 1. 构建一个计算监控 可以用如下的形式构建一个计算监控: ko.computed( evaluator [, targetObject, opti ...

  3. Knockout v3.4.0 中文版教程-6-计算监控-可写的计算监控

    2.可写的计算监控 初学者可能想要跳过本节 - 可写的计算监控是相当高级的部分,在大多数情况下不是必需的. 通常,计算监控是一个通过其他监控值计算出的值,因此是只读的. 令人惊讶的是,可以使计算监控值 ...

  4. Knockout v3.4.0 中文版教程-7-计算监控-依赖跟踪如何工作

    3.依赖跟踪如何工作 初学者不需要知道这一点,但更高级的开发人员将想知道为我们怎么实现KO自动跟踪依赖性和自动更新UI的正确部分... 它其实相当简单优雅,跟踪算法如下: 当你定义一个计算监控,KO立 ...

  5. Knockout v3.4.0 中文版教程-4-通过监控数组工作

    2.通过监控数组工作 1. 监控数组 如果你想检测或者响应一个对象的改变,你用observables.如果你想检测和响应一个集合的改变,使用observableArray.这个在很多情况下都非常有用, ...

  6. Knockout v3.4.0 中文版教程-16-控制流-foreach绑定

    2. 控制流 1. foreach绑定 目的 foreach绑定会遍历一个数组,为每个数组项生成重复的元素标记结构并做关联.这在渲染列表或表格的时候特别有用. 假设你的数组是一个监控数组,之后无论你进 ...

  7. Knockout v3.4.0 中文版教程-1-入门和安装

    英文原版教程:http://knockoutjs.com/documentation/introduction.html 注:此教程根据英文原版翻译,仅作练习,如有不足或错误,请指正 说明: 对原文中 ...

  8. Knockout v3.4.0 中文版教程-11-控制文本内容和外观-text绑定

    2. text绑定 目的 text绑定把传入的参数通过关联的DOM元素来显示文本值. 通常这对像<span>或<em>标签等使用,但技术上你可以对任何元素使用该绑定. 例子 T ...

  9. Knockout v3.4.0 中文版教程-14-控制文本内容和外观-style绑定

    5. style绑定 目的 style绑定用来给关联的DOM元素添加或移除一个或多个样式值.在如下情况很有用,比如,当某些值为负时,高亮显示,或者设置容器元素的宽度来匹配数值的改变. (注意:如果你不 ...

随机推荐

  1. Linux下命令行中的复制和粘贴

    安装gpm:yum install -y gpm* 开启gpm服务:systemctl start gpm 按住鼠标左键,选中想要复制的内容,松开就完成复制,再在复制的位置按右键就完成粘贴.

  2. npm scripts 常用规范总结

    npm scripts 常用规范总结 随着 npm scripts 使用越来越多,需要规范一下, npm run 的使用词. 定义 我定义如下形式: npm run <action>:&l ...

  3. 開玩樹莓派(一):安裝Raspbian系統

    目錄: 開玩樹莓派(一):安裝Raspbian系統 開玩樹莓派(二):配置IP,實現無顯示器局域網內Putty連接和RDP遠程 開玩樹莓派(三):Python編程 開玩樹莓派(四):GPIO控制和遠程 ...

  4. I/O————File对象

    File文件对象 文件和文件夹都是用File代表 创建一个文件对象,(并不会有真正的文件或文件夹被创建) File f1 = new File("d:/lolfilder"); S ...

  5. 解决win64无法添加curl扩展的问题

    网上试了很多方法都无效,最后直接用phpstudy集成安装包中对应版本的php_curl.dll替换即可

  6. Java创建对象的过程

    Java创建对象的过程 Java是一门面向对象的编程语言,在Java程序运行过程中每时每刻都有对象被创建出来.在语言层面上,创建对象通常仅仅是一个new关键字而已,而在虚拟机中,对象的创建又是怎样一个 ...

  7. Mysql->order by SQL 根据多个条件排序

    Mysql中根据多个条件排序:(各个条件间使用逗号隔开)   首先根据class_name字符串长短升序排列,然后根据开始时间降序排列: SELECT * FROM signup_class s OR ...

  8. IE浏览器兼容background-size

    background-size是CSS3新增的属性,IE8以下不支持,通过滤镜实现background-size效果 background-size:contain; // 缩小图片来适应元素的尺寸( ...

  9. ls参数

    -a 全部文件 -A 与a差不多,但是不包括.和..开头的两个目录 -d 仅列出目录 -f 直接列出结果,不进行排序 -h 列出文件大小 -i 列出inode的位置,而非列出文件属性 -l 列出长数据 ...

  10. SP2-0734: 未知的命令开头 "imp scott/..." - 忽略了剩余的行。

    Oracle数据导入报错:SP2-0734: 未知的命令开头 "imp scott/..." - 忽略了剩余的行. 原因:进入sqlplus里是不能执行imp的(sqlplus不认 ...