2013-07-09 56 views
1

我在「小部件」中有此代碼。值是小部件的值,其他則是應用程序中其他位置的數據源。即使它從未被讀取過,計算器也創建了一個值的訂閱。這意味着,當我更新值,補償運行和值設置回等..Knockout計算創建的依賴關係,可寫入但不能讀取

value = ko.observable(1); // Widgets value 
other = ko.observable('a'); // Somewhere else in app 

comp = ko.computed(function() { 
    value(other()); 
    doSomeThingElse(); 
}); 

value(2); 
// comp is run 
value() === 'a'; // true 

基本上我需要補償,如果其他更改爲只運行。我看到現在有一​​個偷看功能,但這只是爲了閱讀。爲什麼計算結果甚至會創建一個永遠不會被讀取的觀察值的訂閱?這非常令人沮喪。有沒有辦法解決?

所述CoMP函數用於上的部件來設置從外部源他們的數據,窗口小部件的實際佈局是:

new Widget({ 
    id: 'widget', 
    initial: 5, 
    observables: { 
     data: function() { 
      var data = client.get('data'); // observable 
      this.value(data); 
      this.color(data.length ? 'red' : 'green'); 
     } 
    } 
}) 

當插件創建它使從observables.data一個新的計算。我們希望保持這個簡單的API,而不必手動訂閱,這會使小部件複雜化。

編輯: 問題是逸岸我的代碼錯誤,上面的例子是suppost加以簡化,但實際上切出的問題。如果有興趣,請看這個小提琴http://jsfiddle.net/dominata/hu6Fr/

經過考慮,我們將使用此模型而不是純粹用於副作用的計算。我同意這更多的是他們打算如何使用。

new Widget({ 
    id: 'widget', 
    initial: 5, 
    value: function() { 
     return client.get('data'); 
    }, 
    color: function() { 
     return client.get('data').length ? 'red' : 'green'; 
    } 
}) 
+0

一般來說,這不是一個好的做法,你的計算有副作用,即設置外部變量。 – nemesv

+0

我再次考慮過這一點,並決定我同意我們計算出來的副作用不是最好的想法,可能會導致不良的工作實踐,也就是使用它們來設置不應該與他們設置的事情混淆。我們將按照用戶的返回值進行計算,並且只包含更多的值。 – DomA

回答

1

設置value在您的計算器中不會創建訂閱。您將訂閱other。唯一的問題是如果您訪問value作爲doSomethingElse的一部分。

這裏是一個小提琴表明這些計算的最初評估,但在更新後value沒有評估:http://jsfiddle.net/rniemeyer/exV92/

我@nemesv,你很可能要小心在計算設置可觀察到的同意。你目前的情況應該可行(禁止doSomethingElse中的行爲)。

另一種選擇可能是使用手動訂閱。如果您想更新value只有當other變化,那麼你可以做:

other.subscribe(function(newValue) { 
    value(newValue); 
    doSomethingElse(); 
}); 

具有手動訂閱只會觸發時的具體觀察的變化,所以你不必擔心哪些依賴你訪問。

+0

那尷尬,顯然我沒有檢查我自己的例子。我把一個更完整的小提琴放在一起來展示問題,並且這樣做意識到了我的方式的錯誤。 Value是一個包裝函數,它在實際的observable上得到並設置,但包裝函數總是讀取observable的值!完全監督。這是一個有興趣的人的小提琴。 http://jsfiddle.net/dominata/hu6Fr/ – DomA