2013-07-24 22 views
2

我需要一個時間戳來更新值。由於我不想進入這裏的原因,value是一個可寫的計算結果,指向一個valueInstance觀測值,所以它們基本上顯示相同的數據。Knockout訂閱正在意料之外的評估

如果我訂閱observable,它按預期工作,只有當observable發生變化時纔會觸發。如果我訂閱了計算器,它立即引發一個錯誤的時間戳,即使observable仍未定義。這是怎麼回事?

http://jsfiddle.net/bNXhm/

更新:看起來像當計算這只是發生了deferEvaluation: true

http://jsfiddle.net/bNXhm/1/

function VM(){ 
    var self = this; 

    self.valueInstance = ko.observable(); 
    self.value = ko.computed({ 
     read: function() { 
      return self.valueInstance(); 
     }, 
     write: function (value) { 
      self.valueInstance(value); 
     }, 
     deferEvaluation: true 
    }); 

    self.timeStamp1 = ko.observable(); 
    self.value.subscribe(function (newValue) { 
     self.timeStamp1(new Date()); 
    }); 

    self.timeStamp2 = ko.observable(); 
    self.valueInstance.subscribe(function (newValue) { 
     self.timeStamp2(new Date()); 
    }); } 
+0

什麼是你的問題?我沒有看到任何意外的行爲。 – Damien

+0

即使'value'沒有改變,'value.subscribe'也會在初始加載時觸發。訂閱應該只在值更改時觸發。 – Homer

回答

1

當您創建一個observable時,除非將deferEvaluation設置爲true,否則它將被評估。 當可觀察(或計算)的評估時,它總是通知他們的用戶。在這一點上沒有與之前的值進行比較(只有當值改變時才通知)。

「無用通知檢查」是在observable的setter中進行的。

因此,在您的代碼中,當您使用deferEvaluation爲false時,將立即評估讀取函數,並且會通知訂閱者。但目前沒有訂戶。這就是爲什麼沒有設定時間跨度。

當您使用deferEvaluation:true時,評估過程是applyBindings函數中的延遲。在這個時候你已經訂閱了,這就是爲什麼時間會被設置。

爲了解決您的問題,我會創建一個變量來存儲何時應該開始記錄更改。

function VM(){ 

    var self = this; 
    self.logged = false; 


    self.valueInstance = ko.observable(); 
    self.value = ko.computed({ 
     read: function() { 
      return self.valueInstance(); 
     }, 
     write: function (value) { 
      self.valueInstance(value); 
     }, 
     deferEvaluation: true 
    }); 

    self.timeStamp1 = ko.observable(); 
    self.value.subscribe(function (newValue) { 
     if(self.logged) 
      self.timeStamp1(new Date()); 
    }); 

    self.timeStamp2 = ko.observable(); 
    self.valueInstance.subscribe(function (newValue) { 
     if(self.logged) 
      self.timeStamp2(new Date()); 
    }); 
} 
var vm = new VM(); 
ko.applyBindings(vm); 
vm.logged = true; 

我希望它能幫助

See fiddle

1

當你deferEvalaution的計算不計算,直到有人請求它的價值。這發生在綁定時。評估時,它會通知任何訂戶。這可以解釋爲什麼您的訂閱受到影響。