(一)Knockout 計算屬性
Computed
首先,創建一個view model如下:
<body> <p>The fullname is: <span data-bind="text: fullName"></span></p> </body> <script> function MyViewModel() { this.firstName = ko.observable("Chiaki"); this.lastName = ko.observable("Izumi"); this.fullName = ko.computed(function() { return this.firstName() + " " + this.lastName(); }, this); } ko.applyBindings(new MyViewModel()); </script>
每當firstName或是lastName中至少一個變化的時候,就會調用一次ko.computed來生成fullName並反映在UI中。
從以上示例中也可以看到,ko.computed有兩個參數,第一個是聯系兩個observable並生成fullName的函數,第二個是this。第二個參數指定了第一個參數中的this的值(這個看起來的確有些怪異,可以留作以後研究),按照文檔中的說法,javascript中的函數在默認情況下並不是object的一部分,所以需要指定this的值。
也有一種通用的簡化方式,即將this在構造函數一開始就賦給另一個變量,這樣在之後需要用到this的部分即可以通過調用另一個變量來實現:
function MyViewModel() {
var self = this;
self.firstName = ko.observable("Chiaki");
self.lastName = ko.observable("Izumi");
self.fullName = ko.computed(function() {
return self.firstName()+ " " + self.lastName();
});
}
個人分析,之所以能夠通過這種方式來簡化,跟javascript中的this機制有關,可能在javascript中每當遇到一個this的時候就分析當前的object到底是哪個,進而對this進行替代,但是進入到ko.computed函數裏面之後,由於函數並不算是object的一部分,this的值也就不再是當前的object(MyViewModel),而變成了window,使用self以後就涉及到閉包的問題了,使得self的值並不會更改,這個可以留作以後研究。
如果computed observable知識基於一些observable的簡單計算的話,使用pureComputed
會比computed更好,如下:
self.fullName = ko.pureComputed(function() {
return self.firstName()+ " " + self.lastName();
})
我們也可以對computed或是pureComputed進行強制訂閱,如下:
this.fullName = ko.pureComputed(function() {
return this.firstName() + " " + this.lastName();
}, this).extend({notify: "always"});
同樣的,可以通過調用extend方法中的rateLimit屬性來指定響應的延時。
在某些時候,我們可能需要判定某個變量到底是不是computed observable,這時可以用到ko.isComputed來進行判斷,類似的方法還包括isObservablem,isWritableObservable等,其中isObservable對於observables、observable arrays、computed observables均會返回true;isWritableObservable對於observables、observable arrays、writable computed observables均會返回true,這部分可以留作以後研究。
參考:
官網,computedObservables
CharlieYuki,KnockoutJs學習筆記(三),Using computed observables
PureComputed
Pure computed observables相對於一般的computed observables,在性能和存儲上有優勢,這是因為pure computed observables在不存在訂閱者的時候是不會保持訂閱關系的。這也使得pure computed observables有如下兩點特點:
- 可以防止沒有被訂閱的computed observables的存儲泄露。
- 可以降低因重復計算未被訂閱的computed observables而造成的運算過載。
一個pure computed observable能夠依據它是否擁有訂閱者而自動地在兩種狀態下切換:
1.當不存在訂閱者的時候,pure computed observable會進入休眠狀態,此時的它,會關閉所有依賴於它的訂閱關系,同時也不會再追蹤它所關聯的observables。一旦處於休眠狀態的computed observable的值被讀取的話,它就需要重新計算以便以確保值得正確性。
2.當它擁有訂閱者的時候,pure computed observable會進入監聽狀態。一旦進入監聽狀態,它會立即調用它的function和訂閱程序來追蹤它所關聯的observables。在這種狀態下,pure computed observables和普通的computed observables無異。更為詳細的內容需參考How dependency tracking works部分。
按照文檔的說明,選擇pure computed observables有兩條原則。一是computed observable在運算的時候不能產生副作用(不能對其他的observables產生影響);二是computed observable的值應該僅僅依賴於它所關聯的observables的值,而不是其他隱含的信息。
Pure computed observables有兩種定義方式:
this.fullName = ko.pureComputed(function() {
return this.firstName() + " " + this.lastName();
}, this);
或者
this.fullName = ko.computed(function() {
return this.firstName() + " " + this.lastName();
}, this, { pure: true });
參考:
官網,Pure computed observables
(一)Knockout 計算屬性