计算监控属性(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({ });
延缓或抑制更改通知
通常情况下,监控属性值改变会立即通知其用户。但是,如果一个监控属性频繁更新会带来高昂的数据传输代价,你可以通过限制或延迟变更通知获得更好的性能。这是通过使用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) && ) { 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>