依赖跟踪如何工作的(How dependency tracking works)
这一块主要是理论的讲解,本人刚接触这块不久,就不敢翻译了,请参见园子里其他人的现有文章 http://www.cnblogs.com/TomXu/archive/2011/11/22/2256820.html
文章内容:
新手没必要知道太清楚,但是高级开发人员可以需要知道为什么依赖监控属性能够自动跟踪并且自动更新UI…
事实上,非常简单,甚至说可爱。跟踪的逻辑是这样的:
- 当你声明一个依赖监控属性的时候,KO会立即调用执行函数并且获取初始化值。
- 当你的执行函数运行的时候,KO会把所有需要依赖的依赖属性(或者监控依赖属性)都记录到一个Log列表里。
- 执行函数结束以后,KO会向所有Log里需要依赖到的对象进行订阅。订阅的callback函数是重新运行你的执行函数。然后回头重新执行上面的第一步操作(并且注销不再使用的订阅)。
- 最后KO会通知上游所有订阅它的订阅者,告诉它们我已经设置了新值。
所有说,KO不仅仅是在第一次执行函数执行时候探测你的依赖项,每次它都会探测。举例来说,你的依赖属性可以是动态的:依赖属性A代表你是否依赖于依赖属性B或者C,这时候只有当A或者你当前的选择B或者C改变的时候执行函数才重新执行。你不需要再声明其它的依赖:运行时会自动探测到的。
另外一个技巧是:一个模板输出的绑定是依赖监控属性的简单实现,如果模板读取一个监控属性的值,那模板绑定就会自动变成依赖监控属性依赖于那个监控属性,监控属性一旦改变,模板绑定的依赖监控属性就会自动执行。嵌套的模板也是自动的:如果模板X render模板 Y,并且Y需要显示监控属性Z的值,当Z改变的时候,由于只有Y依赖它,所以只有Y这部分进行了重新绘制(render)。
使用peek控制依赖(Controlling dependencies using peek)
(注:peek的具体作用还没用到,还在做一些有针对性的场景做验证,目前按文档的了解,可能就是防止循环引用时的作用比较大)
knockout会对依赖进行自动跟踪,但有时可能并不能达到我们的效果,我们可能需要手动控制哪一个依赖需要更新(我还没碰到过这种场景),尤其是当computed observable有一系列动作时,例如Ajax请求。peek函数可以访问observable 或者 computed observable而不用创建依赖。
下面的例子,computed observable用来使用Ajax方式重新加载currentPageData,它依赖两个observable 属性。当pageIndex改变时computed observable就会更新,但是会忽略selectedItem的改变,因为访问它使用了peek. 在这个示例中,selectedItem可能仅是在数据重新加载时做跟踪用的(即是:只使用它的值,但是它的值改变时,并不会重新加载数据(待验证))。
ko.computed(function() {
var params = {
page: this.pageIndex(),
selected: this.selectedItem.peek()
};
$.getJSON('/Some/Json/Service', params, this.currentPageData);
}, this);
注:可以使用extender扩展,达到阻止computed observable更新过于频繁的效果。
注:为什么循环依赖没有意义
computed observable应该是有许多的observable输入,但是只有一个值输出。因此,不应该在你的依赖链中出现循环。循环和递归是不一样的,它比较像Excel里两个单元格相互引用。它会导致无限循环。
当发生这种情况时knockout是怎么做的呢?它是这样来避免这种情况发生的:当已经在计算时knockout不会重新进行下次计算。这不会影响到你的代码。这有两种情况:当两个computed observables互相依赖时(可能其中一个或两个使用了deferEvaluation选项),或者一个computed observable向另一个它依赖的observable定入时(或者是直接的,也可能是通过依赖链有关系)。如果你出现这种情况,又需要避免循环依赖,就需要使用peek函数。
依赖跟踪如何工作的(How dependency tracking works)的更多相关文章
- Knockout v3.4.0 中文版教程-7-计算监控-依赖跟踪如何工作
3.依赖跟踪如何工作 初学者不需要知道这一点,但更高级的开发人员将想知道为我们怎么实现KO自动跟踪依赖性和自动更新UI的正确部分... 它其实相当简单优雅,跟踪算法如下: 当你定义一个计算监控,KO立 ...
- 使用-MM生成include指令和依赖生成(make include directive and dependency generation with -MM)
I want a build rule to be triggered by an include directive if the target of the include is out of d ...
- SVN合并时报错:合并跟踪不允许丢失子树Merge tracking not allowed with missing subtrees; try restoring these items
使用的是TortoiseSVN; Merge tracking not allowed with missing subtrees; try restoring these items 下面会有跟着几 ...
- 建立MVC的依赖项注入 Setting up MVC Dependency Injection 精通ASP-NET-MVC-5-弗瑞曼
The result of the three steps I showed you in the previous section is that the knowledge about the i ...
- Knockout 新版应用开发教程之Computed Observables
Computed Observables 如果你有监控属性firstName和lastName的话,此时如果你想要显示全名? 这个时候computed(以前叫做依赖)监控属性就出马了,这是一个函数用来 ...
- Knockout应用开发指南 第二章:监控属性(Observables)
原文:Knockout应用开发指南 第二章:监控属性(Observables) 关于Knockout的3个重要概念(Observables,DependentObservables,Observabl ...
- knockout.js
最近在使用knockout这个JS的MVVM模型,真的很不错,每次去查英文的文档,的确很累的,抽空的时候就把看到的文档按自己的理解翻译一下.当然我不是逐字的翻译. knockout的官方说明:http ...
- (一)Knockout 计算属性
1 Computed 首先,创建一个view model如下: <body> <p>The fullname is: <span data-bind="text ...
- 第二章:监控属性(Observables)
关于Knockout的3个重要概念(Observables,DependentObservables,ObservableArray),本人无法准确表达它的准确含义,所以暂定翻译为(监控属性.依赖监控 ...
随机推荐
- 两种画线算法(DDA&Bersenham)
DDA(digital differential analyzer) 由直线的斜截式方程引入 对于正斜率的线段,如果斜率<=1,则以单位x间隔(δx=1)取样,并逐个计算每一个y值 Yk+1 = ...
- 转:iOS程序main函数之前发生了什么
原文地址:http://blog.sunnyxx.com/2014/08/30/objc-pre-main/ 我是前言 一个iOS app的main()函数位于main.m中,这是我们熟知的程序入口. ...
- nodejs 包引用的终极结论
通常我们用exports 或module.exports 来导出一个文件中的接口和字段,用require来引用导出的对象.那么这个exports 和 module.exports到底有啥关联呢? 1. ...
- centos 日常操作指令
ls ls -li 查看当前目录下所有目录 ls -al 查看当前目录下所有目录包括隐藏文件 CD cd 目录 跳转指定目录 cd ..返回上级目录 cd / 返回根目录 VI 1. 使用vi进 ...
- C#模板打印功能-模板为WPS或Excel
//---WPS----- using EtApp = ET; using System.Reflection; using System.Runtime.InteropServices; using ...
- Eclipse主题设置
1. 内部编辑区域主题 Eclipse黑色主题包 下载主题包解压到Eclipse安装目录下的dropins目录,重启Eclipse,Windows—>Preferences—>Genera ...
- 【Python之路】第十一篇--CSS
css CSS是Cascading Style Sheets的简称,中文称为层叠样式表,用来控制网页数据的表现,可以使网页的表现与数据内容分离. 一.css的四种引入方式 1.行内式 行内式是在标记的 ...
- SQL 小笔记
如何得到字段的类型 select sql_variant_property(ID,'BaseType') from tb
- A*寻路算法 (cocos2d-js详细代码)
看了几天的A*算法,感觉要成为一个游戏开发者,有必要把这个著名的算法拿到手. 网上有此算法的代码片段,但主要还是些模板类的伪代码,所以想分享一段完整的A*算法代码供大家更好的理解!(这里使用的是js语 ...
- PHP中date函数月和日带0问题
一.带零 echo date('Y-m-d'); 2012-08-08 二.不带零 echo date('Y-n-j'); 2012-8-8 以下为参数详解(转载): a - "am&q ...