初学者无需了解这些 ,但是很多高级程序员想知道我们为什么可以保持跟踪这些依赖以及可以正确的更新到UI中。它其实很简单。跟踪算法是这样的:

  1. 无论何时你定义了一个computed observable,KO 立即执行它的执行函数来获取初始值。
  2. 当执行函数正在运行,KO会在执行函数中所有使用到的observables之间(包括其它的computed observable)建立订阅关系。这个订阅回调必定使执行函数再次运行,循环整个过程回到第一步(释放所有的订阅关系并且不再使用)。
  3. KO想所有订阅者通知你的computed observable的新值消息。

所以,KO并不只是在第一次运行执行函数的时候发现依赖关系-它会在每一次执行的时候都再发现测依赖关系。这意味着这些依赖可以动态变化:依赖A可以决定computed observable是否也依赖于B或C。然后它只会在A或者B或C变化时被重新执行一次。 你不需要声明依赖,它们在代码运行时确定。

另一个巧妙的技巧是声明式绑定作为computed observables来简单实现。这样,如果一个绑定读取一个observable的值,那个绑定就依赖于了这个observable,当它发生变化的时候就会重新激活这个绑定。(原文是The other neat trick is that declarative bindings are simply implemented as computed observables. So, if a binding reads the value of an observable, that binding becomes dependent on that observable, which causes that binding to be re-evaluated if the observable changes.这个地方我感觉翻译的有毛病。)

使用peek控制依赖

KO的自动依赖跟踪通常能准确的知道你想要什么。但是你有时可能需要控制哪些observable将要更新你的computed observable,尤其是如果这个computed observable执行一个很简短的行为例如发送一个ajax请求。. peek方法让你可以无需创建依赖就能访问一个observable或者computed observable。

在下面的例子中,computed observable使用ajax来重新为一个叫做currentPageData的observable加载数据,它向服务器传递的数据params中有两个observable属性,也就是说无论何时pageIndex属性发生了变化这个computed observable 都将会更新,也就是会运行json的请求, 但是它忽略了selectedItem的变化,因为它使用peek来进行访问. 在这种情况下,当一系列新的数据加载的时候,用户可能希望为了追踪的目的只使用selectedItem的当前值 。

ko.computed(function() {
var params = {
page: this.pageIndex(),
selected: this.selectedItem.peek()
};
$.getJSON('/Some/Json/Service', params, this.currentPageData);
}, this);

注意: 为什么循环依赖没有意义

Computed observables 应该是将一些observable输入映射为一个单独的observable输出。这样的话在你的依赖链中形成循环是毫无意义的。 循环可能并不像递归;他们将类似于有两个电子表格单元,计算彼此的功能. 这将导致一个无限的循环。

那么如果你在你的依赖中出现了循环依赖那么ko会怎么处理呢? 它通过下面的规则来避免无限的循环::如果computed正在被执行 Knockout 将不会重新激活(执行)它。 这不会影响你的代码。在两种情况下是相关的: 当两个compute observables相互依赖,或者当一个computed observable 向另外一个拥有依赖的observable写入数据的收 (直接写或者通过一个依赖链中). 如果您需要使用这些模式之一,并希望完全避免循环依赖,您可以使用上面所述的peek功能。

总结说明,这一节算是翻完了,但是很多知识点理解上还是有问题。这一节的重点就是那个peek,它的主要作用就是:如果computed observable中使用了其它的observable,那么当那些observable有更新的时候会让这个computed observable再执行一次,如果这里面有ajax操作或其它耗时操作没有必要,那么我们使用peek可以单向解除这个依赖,当那些observable更新时使得我们computed observable无需跟着更新。

Knockoutjs官网翻译系列(四) computed中依赖追踪是如何工作的的更多相关文章

  1. Knockoutjs官网翻译系列(三) 使用Computed Observables

    书接上回,前面谈到了在视图模型中可以定义普通的observable属性以及observableArray属性实现与UI元素的双向绑定,这一节我们继续探讨第三种可实现绑定的属性类型:computed o ...

  2. Knockoutjs官网翻译系列(一)

    最近马上要开始一个新项目的研发,作为第一次mvvm应用的尝试,我决定使用knockoutjs框架.作为学习的开始就从官网的Document翻译开始吧,这样会增加印象并加入自己的思考,说是翻译也并不是纯 ...

  3. Knockoutjs官网翻译系列(二) Observable 数组

    承接前文,前文书说道了KO框架中如何使用observable的视图模型属性来与UI元素进行绑定并自动进行双向更新的事儿.observable属性除了服务基础数据类型之外,还定义了专门为服务数组类型的o ...

  4. 20.翻译系列:Code-First中的数据库迁移技术【EF 6 Code-First系列】

    原文链接:https://www.entityframeworktutorial.net/code-first/migration-in-code-first.aspx EF 6 Code-First ...

  5. 8.翻译系列: EF 6中配置领域类(EF 6 Code-First 系列)

    原文地址:http://www.entityframeworktutorial.net/code-first/configure-classes-in-code-first.aspx EF 6 Cod ...

  6. 10.翻译系列:EF 6中的Fluent API配置【EF 6 Code-First系列】

    原文链接:https://www.entityframeworktutorial.net/code-first/fluent-api-in-code-first.aspx EF 6 Code-Firs ...

  7. 【官网翻译】性能篇(四)为电池寿命做优化——使用Battery Historian分析电源使用情况

    前言 本文翻译自“为电池寿命做优化”系列文档中的其中一篇,用于介绍如何使用Battery Historian分析电源使用情况. 中国版官网原文地址为:https://developer.android ...

  8. ECharts概念学习系列之ECharts官网教程之在 webpack 中使用 ECharts(图文详解)

    不多说,直接上干货! 官网 http://echarts.baidu.com/tutorial.html#%E5%9C%A8%20webpack%20%E4%B8%AD%E4%BD%BF%E7%94% ...

  9. 【工利其器】必会工具之(三)systrace篇(1)官网翻译

    前言 Android 开发者官网中对systrace(Android System Trace)有专门的介绍,本篇文章作为systrace系列的开头,笔者先不做任何介绍,仅仅翻译一下官网的介绍.在后续 ...

随机推荐

  1. DNS递归和迭代原理

    11.3.7 DNS递归解析原理 “递归解析”(或叫“递归查询”,其实意思是一样的)是最常见,也是默认的解析方式.在这种解析方式中,如果客户端配置的本地名称服务器不能解析的话,则后面的查询全由本地名称 ...

  2. Chapter 2. OpenSSL的安装和配置学习笔记

    Chapter 2. OpenSSL的安装和配置学习笔记 2.1 在linux上面安装OpenSSL我还是做点No paper事情比较在行,正好和老师的课程接轨一下.以前尝试过在Windows上面安装 ...

  3. es watcher

    https://www.elastic.co/products/watcher https://www.elastic.co/blog/watcher-beta-goes-public-you-kno ...

  4. POJ1836 Alignment(LIS)

    题目链接. 分析: 从左向右求一遍LIS,再从右向左求一遍LIS,最后一综合,就OK了. 注意: 有一种特殊情况(详见discuss): 8 3 4 5 1 2 5 4 3 答案是:2 AC代码如下: ...

  5. POJ 1287 Networking

    题目链接: poj.org/problem?id=1287 题目大意: 你被分派到去设计一个区域的连接点,给出你每个点对之间的路线,你需要算出连接所有点路线的总长度. 题目输入: 一个数字n  代表有 ...

  6. SET NOCOUNT (Transact-SQL)

    阻止在结果集中返回显示受 Transact-SQL 语句或存储过程影响的行计数的消息. 语法 SET NOCOUNT { ON | OFF } 注释  当 SET NOCOUNT 为 ON 时,不返回 ...

  7. 《Linear Algebra and Its Applications》-chaper1-向量方程、矩阵方程和线性方程组

    向量: 向量的基本运算:向量的运算最基本的一件事情,就是基于它n个分量上进行,即对于两个分量的向量a = <a1,a2>,b = <b1,b2>,有a + b = <a1 ...

  8. F - Power Network - poj 1459(简单最大流)

    题目大意:题目说了一大堆,其实都是废话......让人有些不知所云,其实就是给了一些电厂,和一些消费点,然后里面有一些路线什么的,求出消费点可以最多消费的电量是多少. 输入大意: 分析:懂了题意就是一 ...

  9. 百度地图API 重新生成点聚合的功能

    百度点聚合用来解决加载大量点要素到地图上产生覆盖现象的问题,并提高性能. http://api.map.baidu.com/library/MarkerClusterer/1.2/docs/symbo ...

  10. 解决从VIM复制出来的代码格式错乱或对齐的问题

    这篇文适合给使用VIM的小鸟看,不太适合老鸟 之前有一个问题就是只要是从VIM复制出来的代码,无论是放到CSDN还是GITHUB上面都会变得非常难看. 在VIM里面你看着以为对齐了,实际没有.先说一下 ...