Knockoutjs官网翻译系列(三) 使用Computed Observables
书接上回,前面谈到了在视图模型中可以定义普通的observable属性以及observableArray属性实现与UI元素的双向绑定,这一节我们继续探讨第三种可实现绑定的属性类型:computed observables,我称它为计算observable(说实话关于observable怎么翻译我还真拿不准)。
要是你在视图对象中已经定义了一个叫firstName的observable属性和一个叫lastName的observable属性,而你想显示这个人的全名那要如何处理呢?这种情况下就到了computed observables 登场的时候了- 它们是一种依赖于其它observables的方法。并且当依赖的这些observables发生变化的时候会自动进行内容的更新。来个Demo吧:
- function AppViewModel() {
- this.firstName = ko.observable('Bob');
- this.lastName = ko.observable('Smith');
- }
此时你可以添加一个computed observable来显示全名
- function AppViewModel() {
- this.fullName = ko.computed(function() {
- return this.firstName() + " " + this.lastName();
- }, this);
- }
然后像这样绑定UI
- The name is <span data-bind="text: fullName"></span>
绑定之后之后无论firstName或者lastName什么时候发生了变化,fullName会自动更新为最新的值。(也就是说当依赖的observable发生变化的时候computed中放置的激活函数每次都会被调用, 并且无论你返回什么都会传递给相应的观察者,比如UI元素或者其它的computed observables)。
依赖链
当然了,因此你也可能创造出一条computed observables链,例如像下面这样的场景:
- 一个叫items的observable属性,它代表一系列对象
- 另一个叫selectedIndexes的observable属性,代表了被用户选中的项的下表索引
- 一个叫selectedItems的computed observable ,它返回一个与selectedIndex相关的对象数组。
- 另一个computed observable,它返回true或者false,如果selectedItems数组中有值那么返回true,否则返回。某些UI元素例如button,它是否可用取决于这个computed observable的返回值。
修改items
或者 selectedIndexes
会波及并更新到链条中的computed observables,进而会更新绑定到它们的UI元素。
关于‘this’
ko.computed中的第二个参数(上面示例中的this
) ,当computed observable函数被调用的时候定义了this到底是什么。如果不传递这个值 ,是不能像代码中那样引用this.firstName或者this.lastName的。有经验的Javascript的程序员应该不会有什么疑惑,因为在computed observable中this指代的就不是AppViewModel对象了,
也就无法访问到里面的属性,所以这里需要重新进行赋值定义。 JavaScript在这一点上看起来很奇怪 。(像C# 和Java 是永远不希望程序员为this进行赋值的, 但是JavaScript需要, 因为它的functions 本身默认是不属于任何对象的。)
- 这里推荐一个比较流行而且简单的处理方式,避免始终考虑this所处的上下文,如果你的视图模型的构造器拷贝一个this的引用到一个单独的变量中(比较经典的可以起名叫
self
),你就可以在其它需要使用之前this的地方使用它,就不用再担心this会被隐式定义成其它对象了,举个例子:
- function AppViewModel() {
- var self = this;
- self.firstName = ko.observable('Bob');
- self.lastName = ko.observable('Smith');
- self.fullName = ko.computed(function() {
- return self.firstName() + " " + self.lastName();
- });
- }
因为self是在function中被捕获的
, 他会在内部functions中始终可用, 例如computed observable的执行函数。
Pure computed observables
如果你的computed observable 只执行简单的计算并返回一个依赖于其它observable的值, 那么最好是这么声明 ko.pureComputed
从而取代一个ko.computed。例如
:
- this.fullName = ko.pureComputed(function() {
- return this.firstName() + " " + this.lastName();
- }, this);
从这个computed声明为pure起 (如果它的调用方法不直接更改其它对象的状态), Knockout 可以更有效的管理它的再次激活方式以及它的内存使用方式。当没有其它代码再依赖这个属性的时候Knockout 会自动挂起或者释放它。(也就是说会有性能上的优化)
防止computed observables 始终通知订阅者
当一个computed observable 返回一个基本类型值的时候 (number, string, boolean, 或者null), 与它有依赖关系的通常只会在它真正发生改变时接收到通知,如果始终返回同一个值,那么就不会接收到通知。 然而, 可以使用内置的notify
extender 保证一个 computed observable’s 的订阅者始终可以在computed observable更新时接收到通知,哪怕更新后的值与之前是相同。使用方式如下:
- myViewModel.fullName = ko.pureComputed(function() {
- return myViewModel.firstName() + " " + myViewModel.lastName();
- }).extend({ notify: 'always' });
延迟更新通知
- for (var prop in myObject) {
- if (myObject.hasOwnProperty(prop) && !ko.isComputed(myObject[prop])) {
- result[prop] = myObject[prop];
- }
- }
通常来讲, 一个computed observable 更新后会立即通知它的订阅者。 但是如果一个 computed observable 有很多依赖并更新时会比较耗时, 你可以通过限制更新的间隔时间来获取一个较好的性能。可通过下面的方式来完成:
- myViewModel.fullName.extend({ rateLimit: 50 });
判断一个属性是不是一个computed observable
在有些场景下,通过编程来判断一个属性是不是computed observable是非常有用的。 Knockout 提供了一个工具方法, ko.isComputed
. 例如在你向后台服务发送数据的时候你可能想把computed observables从提交数据中排除出去。可以这样:
- for (var prop in myObject) {
- if (myObject.hasOwnProperty(prop) && !ko.isComputed(myObject[prop])) {
- result[prop] = myObject[prop];
- }
- }
此外, Knockout 还提供了一些类似的方法可以操作于observables 和 computed observables:
- ko.isObservable - 如果是observables或者observableArray或者computed observables那么就返回true。
ko.isWritableObservable - 如果是observables或者observableArray或者可写computed observables 那么就返回true。
当computed observable 只在你的UI种使用
如果你只需要在你的UI界面上使用复合全称,你可以像如下这样声明:
- function AppViewModel() {
- this.fullName = function() {
- return this.firstName() + " " + this.lastName();
- };
- }
现在你的UI绑定就变成了一个方法调用,如下:
- The name is <span data-bind="text: fullName()"></span>
Knockout 会在幕后创建 computed observable来监测绑定表达式依赖了什么observables,并且如果相关元素之后被删除了也会自动释放他(dispose it)。
好了,下节继续!
Knockoutjs官网翻译系列(三) 使用Computed Observables的更多相关文章
- Knockoutjs官网翻译系列(四) computed中依赖追踪是如何工作的
初学者无需了解这些 ,但是很多高级程序员想知道我们为什么可以保持跟踪这些依赖以及可以正确的更新到UI中.它其实很简单.跟踪算法是这样的: 无论何时你定义了一个computed observable,K ...
- Knockoutjs官网翻译系列(一)
最近马上要开始一个新项目的研发,作为第一次mvvm应用的尝试,我决定使用knockoutjs框架.作为学习的开始就从官网的Document翻译开始吧,这样会增加印象并加入自己的思考,说是翻译也并不是纯 ...
- Knockoutjs官网翻译系列(二) Observable 数组
承接前文,前文书说道了KO框架中如何使用observable的视图模型属性来与UI元素进行绑定并自动进行双向更新的事儿.observable属性除了服务基础数据类型之外,还定义了专门为服务数组类型的o ...
- 【工利其器】必会工具之(三)systrace篇(1)官网翻译
前言 Android 开发者官网中对systrace(Android System Trace)有专门的介绍,本篇文章作为systrace系列的开头,笔者先不做任何介绍,仅仅翻译一下官网的介绍.在后续 ...
- 【官网翻译】性能篇(四)为电池寿命做优化——使用Battery Historian分析电源使用情况
前言 本文翻译自“为电池寿命做优化”系列文档中的其中一篇,用于介绍如何使用Battery Historian分析电源使用情况. 中国版官网原文地址为:https://developer.android ...
- RavenDB官网文档翻译系列第一
本系列文章主要翻译自RavenDB官方文档,有些地方做了删减,有些内容整合在一起.欢迎有需要的朋友阅读.毕竟还是中文读起来更亲切吗.下面进入正题. 起航 获取RavenDB RavenDB可以通过Nu ...
- android測试工具MonkeyRunner--google官网翻译
近期在复习之前的笔记,在回想MonkeyRunner时看了看google官网的内容,写得不错.就翻译出来分享下.事实上google官网真是一个学习的好地方. 基础知识 MonkeyRunner工具提供 ...
- Spring官网阅读(三)自动注入
上篇文章我们已经学习了1.4小结中关于依赖注入跟方法注入的内容.这篇文章我们继续学习这结中的其他内容,顺便解决下我们上篇文章留下来的一个问题-----注入模型. 文章目录 前言: 自动注入: 自动注入 ...
- 卸载 Cloudera Manager 5.1.x.和 相关软件【官网翻译】
问题导读: 1.不同的安装方式,卸载方法存在什么区别?2.不同的操作系统,卸载 Cloudera Manager Server and 数据库有什么区别? 重新安装不完整如果你来到这里,因为你的安装没 ...
随机推荐
- java代码调用rtx发送提醒消息
http://www.cnblogs.com/qstar/archive/2012/02/03/Astar.html 借用一下!好东西
- BZOJ 1021 [SHOI2008]Debt 循环的债务
1021: [SHOI2008]Debt 循环的债务 Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 694 Solved: 356[Submit][S ...
- 64位操作系统 注册 capicom.dll
把capicom.dll 放到c:\windows\syswow64目录 以管理员身份运行c:\windows\syswow64\cmd.exe 执行 regsvr32 capicom.dll ...
- 2013.11.7-21:15_My first Java program
- Python学习打算
背景:本人用python写自动化脚本,基础的东西都会啦.但是呢,鉴于年轻应该好好学习,所以打算再买一本python书籍用来精读. Python 好的博客: Python快速教程(好多,一点也不快速): ...
- ASP.NET 之深入浅出Session和Cookie
在做人事档案管理系统中,对于Session和Cookie的使用后理解更加深刻了,下面对本知识点总结学习. Session是什么? 简单来说就是服务器给客户端的一个编号.当一台WWW服务器运行时,可能有 ...
- 完整版的OpenLDAP搭建全过程
总结: 先写总结,再写正文,嘿嘿嘿.这还是第一次认真的写个文档,写个总结,哈哈.大概在一个月前,第一次听说这个东西,完全没有概念,刚开始的时候看理论的知识,看了几次之后就没看了,看不 ...
- mvc系统过滤器
一.系统过滤器使用说明 1.OutputCache过滤器 OutputCache过滤器用于缓存你查询结果,这样可以提高用户体验,也可以减少查询次数.它有以下属性: Duration:缓存的时间,以秒为 ...
- WINDOWS UPDAET
相信各位或多或少都知道 Windows Update 功能,Windows 有了它就可以随时升级到最新的程序版本,同时对防止安全威胁也能起到很大的作用 在 Windows 7 中,安装完成首次运行 ...
- DB2 递归
公司一直用递归来生成组织机构的树状图.看了上面的文档,应该立马就能写了. 不过前几天,有个功能涉及到下面的状况: 需要组织机构等级为1级的下面所有子机构.且按照一级组织机构分组.大家都觉得很难,哥就一 ...