计算监控属性(Computed Observables)

如果你有一个监控属性firstName,和另一个lastName,你要显示的全名?可以使用计算监控属性来实现-它依赖于一个或多个其他监控属性,每当这些依赖关系的监控属性改变时将会自动更新计算监控属性。

例如,下面的视图模型:

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

可以添加一个计算监控属性来返回全名:

function AppViewModel() {
// ... leave firstName and lastName unchanged ... this.fullName = ko.computed(function() {
return this.firstName() + " " + this.lastName();
}, this);
}

然后将计算监控属性绑定到UI上:

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

这里的fullname将会根据firstname和lastname的改变而改变。

管理”this”关键字

上面的例子中,ko.computed通过定义的this调用视图模型中的其他监控属性。有经验的JavaScript程序员会认为这是很正常的调用,但如果你是个JS初学者会仍然觉得看起来很奇怪。

其中一种流行的方式是,将this关键字赋值给一个JS变量,比如var self,然后使用self调用整个视图模型的监控属性。例如:

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();
});
}

升级版计算监控属性(pureComputed)

在KnockoutJS 3.X中新增加了pureComputed方法,该方法是在Computed方法的基础上改良而来的。其主要作用是防止内存泄露,其次是减少没有必要的计算的开销

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

强制计算监控属性实时通知用户

当赋值一个包含原始值(一个数字,字符串,布尔值,或者为null)监控属性,使用内置的notified ,以确保一个观测监控属性的用户总是得到通知,即使该值是相同的。

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

延缓或抑制更改通知

通常情况下,监控属性值改变会立即通知其用户。但是,如果一个监控属性频繁更新会带来高昂的数据传输代价,你可以通过限制或延迟变更通知获得更好的性能。这是通过使用rateLimit增量实现:

// Ensure updates no more than once per 50-millisecond period
myViewModel.fullName.extend({ rateLimit: 50 });

排除计算监控属性

在某些情况下,您可能要排除一些计算监控属性,防止其发送回服务器。当然可以使用编程方式确定那些监控属性是计算监控属性,然而KO提供了一个实用函数,ko.isComputed以帮助判断那些是计算监控属性。例如:

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

除此之外,KO还提供了一些其他的很有用的函数:

    • ko.isObservable : 对于所有的observable,observable array,computed observable将返回true;

    • ko.isWritableObservable : 对于所有的observable,observable array,writable computed observable返回true;

当计算监控属性只用于UI展示

如果您只需要在界面中使用计算监控属性,你可以声明为:

function AppViewModel() {
// ... leave firstName and lastName unchanged ... this.fullName = function() {
return this.firstName() + " " + this.lastName();
};
}

UI调用可以使用如下方式调用:

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