• Knockout v3.4.0 中文版教程-7-计算监控-依赖跟踪如何工作


    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函数。

  • 相关阅读:
    6.简易计算器
    5.用户密码管理
    4.方法重载
    3.对象数组做参数
    2.迷你DVD管理系统
    1.二维数组计算班级成绩
    31.向数组中插入一个元素
    30.使用Arrays类的各种方法
    Java开发中的23种设计模式详解(转)
    个人代码归档
  • 原文地址:https://www.cnblogs.com/DHclly/p/6291311.html
Copyright © 2020-2023  润新知