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

  • 相关阅读:
    费用流
    平面最近点对
    纸牌均分问题
    cdq分治模板
    费解的开关
    斐波那契和排列组合性质
    主席树
    Springboot使用EasyExcel(仅限自己收藏)
    vue项目中h5移动端中通过flex布局实现首尾固定,中间滚动(借鉴)
    vue路由参数的获取、添加和替换
  • 原文地址:https://www.cnblogs.com/DHclly/p/6235978.html
Copyright © 2011-2022 走看看