計算監控屬性(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>