3.依赖跟踪如何工作

初学者不需要知道这一点,但更高级的开发人员将想知道为我们怎么实现KO自动跟踪依赖性和自动更新UI的正确部分...

它其实相当简单优雅,跟踪算法如下:

  1. 当你定义一个计算监控,KO立即调用其求值函数来获得初始值。
  2. 当求值函数运行,KO添加一个订阅到任何求值函数可读取的监控对象上(包括其他计算监控对象)。订阅的回调函数会触发求值函数重新运行,整个过程循环回到步骤1(释放任何不再使用的旧订阅)。
  3. KO通知任何订阅者获取你的计算监控的新值。

因此,KO不只是在第一次求值程序运行的时候检测依赖关系,每次都会重新检测。这意味着,例如,依赖关系可以动态变化:依赖A可以决定是否计算监控也取决于B或C,那么,它只会重新求值,无论是A或你目前选择的B或C发生变化。您不必声明依赖项:它们在代码执行的运行时中确定。

另一个诀窍是声明性绑定可以看做是计算监控的简单实现。因此,如果一个绑定读取一个监控的值,绑定会依赖于监控,这将导致如果监控发生变化,绑定会重新求值。

1. 使用peek控制依赖

KO的自动依赖跟踪通常如你想要的那样工作。但你可能有时需要确定哪一个监控将导致重新对计算监控求值,特别是如果计算监控执行一些操作,如发送一个Ajax请求。peek函数可以让你访问一个监控或计算监控的值,而不会创建一个依赖。

在下面的例子里,一个计算监控用来重载一个叫做currentPageData的监控对象的值,该计算监控使用Ajax和来自其他两个监控属性的数据进行请求。每当pageIndex的值发生改变时,计算监控会重新求值,但是会忽略selectedItem的改变,因为是使用peek进行访问的。在这种情况下,用户可能想要使用selectedItem当前的值仅用于跟踪当新的数据集加载的时候。

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

注意:如果你想阻止计算监控频繁刷新,请使用频率限制扩展器。

2. 忽略计算中的依赖关系

ko.ignoreDependencies函数适用于如下场景,在你想执行一个计算代码,而计算监控不会重新求值。这在自定义绑定的情况下特别有用,当你想调用的代码可能会访问监控对象,但是你不想再触发基于这些监控对象的值更新。

ko.ignoreDependencies( callback, callbackTarget, callbackArgs );

例如:

ko.bindingHandlers.myBinding = {
update: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
var options = ko.unwrap(valueAccessor());
var value = ko.unwrap(options.value);
var afterUpdateHandler = options.afterUpdate; // the developer supplied a function to call when this binding updates, but
// we don't really want to track any dependencies that would re-trigger this binding
if (typeof afterUpdateHandler === "function") {
ko.ignoreDependencies(afterUpdateHandler, viewModel, [value, color]);
} $(element).somePlugin("value", value);
}
}

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

计算监控被用于映射一组监控对象的输入值进行计算,返回值作为一个简单监控对象的输出。因此,在你的依赖链中循环依赖是没有意义的。循环依赖不同于递归;它类似于两个电子表格单元互相计算对方的值。这会导致一个死循环。

那么,如果你在你的依赖关系图中有一个循环依赖,KO会做什么?它通过执行以下规则避免了无限循环:KO不会在一个计算监控已经在求值的情况下重新求值。这个不可能影响到你的代码。它跟两种情况有关联:当两个计算监控互相依赖(可能有人个使用deferevaluation选项),或者当一个计算监控把值写入另一个有依赖的监控对象(无论是直接依赖或通过依赖链)。如果你想要使用其中某个方式,而且想完全避免循环依赖,你可以使用如上所述的peek函数。

Knockout v3.4.0 中文版教程-7-计算监控-依赖跟踪如何工作的更多相关文章

  1. Knockout v3.4.0 中文版教程-6-计算监控-可写的计算监控

    2.可写的计算监控 初学者可能想要跳过本节 - 可写的计算监控是相当高级的部分,在大多数情况下不是必需的. 通常,计算监控是一个通过其他监控值计算出的值,因此是只读的. 令人惊讶的是,可以使计算监控值 ...

  2. Knockout v3.4.0 中文版教程-8-计算监控-纯计算属性

    4.纯计算属性 纯计算监控在KO 3.2.0中开始引入,比大多数应用程序使计算监控有更大的性能提升和内存优化.这是因为在自身没有订阅的时候不会保持订阅状态.特性如下 阻止内存泄露 - 避免在应用程序里 ...

  3. Knockout v3.4.0 中文版教程-5-计算监控-使用计算监控

    3. 计算监控 1.使用计算监控 如果你有一个监控的属性firstName和另一个lastName,但你想显示全名怎么办? 这就是引入计算监控的原因-这是依赖于一个或多个其他的observables函 ...

  4. Knockout v3.4.0 中文版教程-9-计算监控-API参考

    5.参考 下面的内容描述了如何构建和使用计算监控. 1. 构建一个计算监控 可以用如下的形式构建一个计算监控: ko.computed( evaluator [, targetObject, opti ...

  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 中文版教程-2-监控-通过监控创建视图模型(上)

    2. 监控 1.通过监控创建视图模型 1. 监控 Knockout是基于以下三个核心特性: 监控和依赖跟踪 声明式绑定 模板 在本节,你将第一次了解这三个特性,在这之前,我们先来了解以下MVVM模式和 ...

随机推荐

  1. keil_rtx调试技巧

    超级循环结构的程序调试一般依赖于断点,单步,查看变量和内存变量(keil中的Memory Window 或者 Watch window):而带微操作系统的程序由于加了这个中间层调试方法可能传统的有些区 ...

  2. python学习之j进程和线程:

    每个进程至少有一个线程,python因为每个线程都共用一个GIL全局锁(同时只能运行一个线程),所以不能用多线程(除非重新写C解释器),但是多进程的GIL锁各自独立可多进程. 进程与线程的区别在于一个 ...

  3. python学习day13

    目录 JavaScript Dom jQuery JavaScript JavaScript 是世界上最流行的编程语言. 这门语言可用于 HTML 和 web,更可广泛用于服务器.PC.笔记本电脑.平 ...

  4. memcache学习

    1.memcache和memcached区别 Memcache是该系统的项目名称,Memcached是该系统的主程序文件(字母d可以理解为daemon),以守护程序方式运行于一个或多个服务器中,随时接 ...

  5. Unity里面两种单例模式的实现

    using System; public class Singleton<T> where T : class, new() { private static T m_instance; ...

  6. Java微信公众平台开发(九)--微信自定义菜单的创建实现

    自定义菜单这个功能在我们普通的编辑模式下是可以直接在后台编辑的,但是一旦我们进入开发模式之后我们的自定义菜单就需要自己用代码实现,所以对于刚开始接触的人来说可能存在一定的疑惑,这里我说下平时我们在开发 ...

  7. uvm_config_db——半个全局变量

    UVM中的配置机制uvm_config_db,uvm_config_db机制用于在UVM平台间传递参数.它们通常是成对出现的,set 寄信,而get函数是收信.config 机制大大提高了UVM的验证 ...

  8. HDinsight 系列-使用证书登陆中国区Azure

    使用azure explorer 插件的时候,登陆默认是globle的azure网站,中国区的azure不能直接使用 可以使用auth文件认证 auth 文件生成 az cloud show -o j ...

  9. 从汇编看c++中的多态

    http://www.cnblogs.com/chaoguo1234/archive/2013/05/19/3079078.html 在c++中,当一个类含有虚函数的时候,类就具有了多态性.构造函数的 ...

  10. JAVA 配置

    JAVA 版本为jdk-7u25-windows-x64 Java 下载地址为: .CLASSPATH .;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.j ...