1. 程式人生 > >(一)Knockout 計算屬性

(一)Knockout 計算屬性

定義 休眠 情況下 sel 返回 關系 的確 通過 進行

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