Knockout v3.4.0 中文版教程-8-计算监控-纯计算属性
4.纯计算属性
纯计算监控在KO 3.2.0中开始引入,比大多数应用程序使计算监控有更大的性能提升和内存优化。这是因为在自身没有订阅的时候不会保持订阅状态。特性如下
- 阻止内存泄露 - 避免在应用程序里计算监控不再被引用但是依赖仍然存在。
- 减少计算开销 - 当值不再被监控不会重新计算计算监控的值。
纯计算监控会在两个状态之间自动切换,基于它是否改变了订阅者。
- 当订阅者没有发生改变,它会休眠。当进入休眠状态,它释放所有自身依赖的订阅。在这种状态下,它不会订阅访问求值函数里面的的监控对象(尽管它会继续跟踪它们)。在休眠的时候计算监控的值被读取,如果依赖对象有发生改变,它会自动重新求值。
- 当订阅者发生任何改变。它会苏醒并开始监听。处于监听状态,它会马上订阅所有依赖。在这种状态下,它就像计算监控一样工作。
什么是"纯"函数?
(该概念属于函数式编程)
我们参考了pure
函数的术语,因为这个特性仅可以应用与计算监控,求值程序的纯功能描述如下 :
- 对计算监控求值不会引起任何其他影响。
- 计算监控的值不应该受求值规模或其他隐藏信息导致变化。它的值应该仅仅受程序里面其他监控对象的值导致变化,对于纯函数的定义,都考虑了它的参数。
语法
定义一个纯计算监控的标准方法是使用ko.purecomputed
:
this.fullName = ko.pureComputed(function() {
return this.firstName() + " " + this.lastName();
}, this);
或者你可以使用ko.computed
加pure
选项:
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-计算监控-纯计算属性的更多相关文章
- Knockout v3.4.0 中文版教程-5-计算监控-使用计算监控
3. 计算监控 1.使用计算监控 如果你有一个监控的属性firstName和另一个lastName,但你想显示全名怎么办? 这就是引入计算监控的原因-这是依赖于一个或多个其他的observables函 ...
- Knockout v3.4.0 中文版教程-9-计算监控-API参考
5.参考 下面的内容描述了如何构建和使用计算监控. 1. 构建一个计算监控 可以用如下的形式构建一个计算监控: ko.computed( evaluator [, targetObject, opti ...
- Knockout v3.4.0 中文版教程-6-计算监控-可写的计算监控
2.可写的计算监控 初学者可能想要跳过本节 - 可写的计算监控是相当高级的部分,在大多数情况下不是必需的. 通常,计算监控是一个通过其他监控值计算出的值,因此是只读的. 令人惊讶的是,可以使计算监控值 ...
- Knockout v3.4.0 中文版教程-7-计算监控-依赖跟踪如何工作
3.依赖跟踪如何工作 初学者不需要知道这一点,但更高级的开发人员将想知道为我们怎么实现KO自动跟踪依赖性和自动更新UI的正确部分... 它其实相当简单优雅,跟踪算法如下: 当你定义一个计算监控,KO立 ...
- Knockout v3.4.0 中文版教程-4-通过监控数组工作
2.通过监控数组工作 1. 监控数组 如果你想检测或者响应一个对象的改变,你用observables.如果你想检测和响应一个集合的改变,使用observableArray.这个在很多情况下都非常有用, ...
- Knockout v3.4.0 中文版教程-16-控制流-foreach绑定
2. 控制流 1. foreach绑定 目的 foreach绑定会遍历一个数组,为每个数组项生成重复的元素标记结构并做关联.这在渲染列表或表格的时候特别有用. 假设你的数组是一个监控数组,之后无论你进 ...
- Knockout v3.4.0 中文版教程-1-入门和安装
英文原版教程:http://knockoutjs.com/documentation/introduction.html 注:此教程根据英文原版翻译,仅作练习,如有不足或错误,请指正 说明: 对原文中 ...
- Knockout v3.4.0 中文版教程-11-控制文本内容和外观-text绑定
2. text绑定 目的 text绑定把传入的参数通过关联的DOM元素来显示文本值. 通常这对像<span>或<em>标签等使用,但技术上你可以对任何元素使用该绑定. 例子 T ...
- Knockout v3.4.0 中文版教程-14-控制文本内容和外观-style绑定
5. style绑定 目的 style绑定用来给关联的DOM元素添加或移除一个或多个样式值.在如下情况很有用,比如,当某些值为负时,高亮显示,或者设置容器元素的宽度来匹配数值的改变. (注意:如果你不 ...
随机推荐
- Linux下Java运行.class文件,报错找不到或无法加载主类
classpath配置的错误,所以找不到.class文件. 原先的etc/profile中的classpath配置 export CLASSPATH=$JAVA_HOME/lib/tools.jar ...
- Springboot日志配置探索(主要看logback)(一)
这篇博客是springboot日志配置探索的第一篇,主要讲默认配置下springboot的logback日志框架的配置(即直接使用是怎样的) 首先,是一个SpringBoot的有关日志的说明文档:ht ...
- 086 Partition List 分隔链表
给定一个链表和一个特定值 x,对链表进行分隔,使得所有小于 x 的节点都在大于或等于 x 的节点之前.你应当保留两个分区中每个节点的初始相对位置.例如,给定1->4->3->2-&g ...
- 8593 最大覆盖问题 two pointer
8593 最大覆盖问题 时间限制:50MS 内存限制:1000K提交次数:193 通过次数:88 题型: 编程题 语言: G++;GCC;VC Description 输入格式 第1行是正整数n ...
- 牛客网Java刷题知识点之什么是死锁、死锁产生的4个必要条件、死锁的解除与预防
不多说,直接上干货! https://www.nowcoder.com/ta/review-java/review?query=&asc=true&order=&page=16 ...
- Vue 简单实用---代码可以直接用
<!DOCTYPE html> <html> <head> <title></title> <script src="htt ...
- 利用樹霉派採集溫濕度上傳到OneNET(非完整,僅參考)
看圖: Python代碼: #env /usr/bin/python3 #author Bruce import RPi.GPIO as GPIO import time import json im ...
- 16年毕业的前端er在杭州求职ing
来杭州也有一两个星期了,这个周末下雨,是在没地去,还是习惯性的打开电脑逛技术论坛,想想也是好久没有更新博文了... 背景 因为曾经看过一篇文章面试分享:一年经验初探阿里巴巴前端社招所以来杭州也是带有目 ...
- UVM之uvm_phase
UVM中的phase机制很有意思,它能让UVM启动之后,自动执行所有的流程.UVM 的user guide 中对uvm_phase的定义如下: This base class defines ever ...
- 设置umask
umask 002 例子:umask为003,建立的文件与目录权限是什么? umask为003,所有去掉的属性为-------wx,因此 文件 -rw-rw-r-- 目录 drwxrwxr--