zoukankan      html  css  js  c++  java
  • Knockout v3.4.0 中文版教程-5-计算监控-使用计算监控

    3. 计算监控

    1.使用计算监控

    如果你有一个监控的属性firstName和另一个lastName,但你想显示全名怎么办? 这就是引入计算监控的原因-这是依赖于一个或多个其他的observables函数,无论这些依赖对象什么时候发生改变,它都将自动更新。
    例如,下面给了一个view model 类,

    function AppViewModel() {
        this.firstName = ko.observable('Bob');
        this.lastName = ko.observable('Smith');
    }
    

    您可以添加一个computed observable来返回全名:

    function AppViewModel() {
        this.firstName = ko.observable('Bob');
        this.lastName = ko.observable('Smith');
        // ... 保留firstName和lastName不变 ...
        this.fullName = ko.computed(function() {
            return this.firstName() + " " + this.lastName();
        }, this);
    }
    

    现在你可以绑定到UI元素,例如:

    The name is <span data-bind="text: fullName"></span>
    

    每当firstNamelastName的值更改时,它们都将更新(其任何依赖项发生更改时,都会调用你的求值函数,并且您返回的任何值都将传递给监控者,例如UI元素或其他计算监控)。

    1. 依赖链如何工作

    当然,如果你愿意,你可以创建整个计算监控的链。例如,您可能有:

    • 一个监控对象叫做items表示一个集合
    • 另一个监控对象叫做selectedIndexes存储用户选择集合某一项的索引值
    • 一个计算监控叫做selectedItems以数组的形式返回选中的对象集合
    • 另一个计算监控根据selectedItems里是否有选择项返回truefalse(就像是空的或者未保存)。一些UI元素,比如按钮,可能根据这个值来判断按钮是否可用。

    itemsselectedIndexes的更改将波及到计算监控的链,这反过来会更新绑定到它们的UI元素。

    2. 管理this对象

    ko.computed的第二个参数(我们在上面的例子中传递this的位置)在执行计算监控时定义了它的值。如果没有传递它,它不可能引用this.firstName()this.lastName()。经验丰富的JavaScript编程人员会认为这是显而易见的,但如果你仅仅了解JavaScript,它可能看起来很奇怪。(像C#和Java这样的语言从来不希望程序员可以为this设置一个值,但是JavaScript可以,因为它的函数本身在默认情况不是任何对象的一部分。)

    一种流行的处理方式

    有一个流行的约定,避免了总是需要跟踪this:如果你的viewmodel的构造函数将this赋值到一个不同的变量(通常叫做self),然后在你的viewmodel里可以使用self,而不必担心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在函数闭包中捕获,所以它在任何嵌套函数(例如在计算监控中的求值程序)中保持可用和一致。当涉及到事件处理程序时,这个约定甚至更有用,你将在许多在线实例中看到。

    3. 纯计算监控

    如果你想简单地计算并返回一个基于一些监控依赖的值,那么最好将其声明为ko.pureComputed而不是ko.computed。 例如:

    this.fullName = ko.pureComputed(function() {
        return this.firstName() + " " + this.lastName();
    }, this);
    

    由于这个计算被声明为纯的(即,执行器不直接修改其他对象或状态),KO可以更有效地管理其重新评估和内存使用。如果没有其他代码对它有活动依赖,Knockout将自动挂起或释放它。

    4. 强制计算监控总是通知订阅者

    当一个computed observable返回一个原始值(一个数字,字符串,布尔,或null),依赖监控通常只有在值实际改变时才进行通知。但是,可以使用内置notify extender来确保computed observable的订阅者总是在更新时通知,即使该值是相同的。 您可以这样使用扩展器:

    myViewModel.fullName = ko.pureComputed(function() {
        return myViewModel.firstName() + " " + myViewModel.lastName();
    }).extend({ notify: 'always' });
    

    5. 延迟或阻止更改通知

    通常情况下,一个计算监控对象只要发生改变就会立即通知订阅者。但是一个计算监控对象有很多依赖或触发一直更新,代价会很大,通过限制或延迟监控到的更改通知,可以获得更好的性能。可以使用频率限制扩展器来完成,如下:

    // 确保每50毫秒内通知改变不超过一次
    myViewModel.fullName.extend({ rateLimit: 50 });
    

    6. 确定属性是否应是计算监控值

    在某些情况下,以程序的方式确定某个属性是否是计算监控对象是很有用的。 KO提供了一个工具函数,ko.isComputed来帮助处理这种情况。例如,您可能希望从返回服务器的数据中排除计算监控值。

    for (var prop in myObject) {
        if (myObject.hasOwnProperty(prop)&&!ko.isComputed(myObject[prop])) {
            result[prop] = myObject[prop];
        }
    }
    

    此外,KO提供了类似的功能,可以操作监控和计算监控:

    • ko.isObservable - 对于监控对象,监控数组和所有计算监控对象返回true。
    • ko.isWritableObservable - 对于监控对象,监控数组和可写计算监控(也称为ko.isWriteableObservable)返回true。

    7. 当计算监控值仅在您的UI中使用

    如果你只需要在UI中使用组合全名,你可以声明它:

    function AppViewModel() {
        // ... 保留firstName和lastName...
        this.fullName = function() {
            return this.firstName() + " " + this.lastName();
        };
    }
    

    现在你绑定的UI元素变成方法调用,比如:

    The name is <span data-bind="text: fullName()"></span>
    

    KO将在内部创建一个计算监控,以便检测该监控表达式的依赖,并且在关联的元素在后面移除的时候自动释放它。

  • 相关阅读:
    Find the Smallest K Elements in an Array
    Count of Smaller Number
    Number of Inversion Couple
    Delete False Elements
    Sort Array
    Tree Diameter
    Segment Tree Implementation
    Java Programming Mock Tests
    zz Morris Traversal方法遍历二叉树(非递归,不用栈,O(1)空间)
    Algorithm about SubArrays & SubStrings
  • 原文地址:https://www.cnblogs.com/DHclly/p/6235978.html
Copyright © 2011-2022 走看看