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. 087 Scramble String 扰乱字符串

    给定一个字符串 s1,我们可以把它递归地分割成两个非空子字符串,从而将其表示为二叉树.下图是字符串s1 = "great"的一种可能的表示形式.    great   /    \ ...

  2. STM32使用注意事项

    一 IO引脚: 1.1 PC13~PC15作为IO输出的限制,PC13/PC15输出最大2MHZ,负载2PF,驱动电流不超过3mA,所以不能用来驱动LED. 2 输出的引脚是否可以用来读引脚: cas ...

  3. disasters

    1.list all the natural disasters to the best of your knowledge. 2.What are the possible causes for s ...

  4. 图像分类丨ILSVRC历届冠军网络「从AlexNet到SENet」

    前言 深度卷积网络极大地推进深度学习各领域的发展,ILSVRC作为最具影响力的竞赛功不可没,促使了许多经典工作.我梳理了ILSVRC分类任务的各届冠军和亚军网络,简单介绍了它们的核心思想.网络架构及其 ...

  5. C# winwordcontrol控件编程

    C# word控件WinWordControl可创建.编辑.保存word. 1.使用代码直接创建word文件,同时可以添加页眉.内容.图片及表格,示例代码: /// <summary>   ...

  6. MVC验证注解(不包含自定义验证)

  7. ReactiveCocoa 响应式函数编程

    简介 ReactiveCocoa(简称为RAC),RAC具有函数响应式编程特性,由Matt Diephouse开源的一个应用于iOS和OS X的新框架. 为什么使用RAC? 因为RAC具有高聚合低耦合 ...

  8. LR中webservice服务测试的脚本

    Action(){ /* 测试QQ是否在线的功能接口 输入参数:QQ号码 String,默认QQ号码:8698053. 返回数据:String,Y = 在线:N = 离线:E = QQ号码错误:A = ...

  9. C#调用CMD程序

    最近写了两个小程序都要调用Windows自带的命令行程序,一个是调用Openfiles.exe查询正在编辑的共享文档,一个是调用DiskPart.exe查询硬盘状态.两种命令行程序调用有点不同,记录一 ...

  10. Win7下vc++6.0打开项目出现问题的解决方案

    Win7下vc++6.0打开项目出现Microsoft(R) Developer Studio以及Unable to register this add-in because its DLLRegis ...