2012-10-24 38 views
3

我如何更改subscribe函數內可觀察值的值? 例如我如何更改subscribe函數內可觀察值的值?

JS型號:

function Model(){ 
    self = this; 
    self.Test = ko.observable(2); 
    self.Test.subscribe(function(){ 
     if (/**Some bool expression**/) { 
     self.Test(2); 
     } 
    }); 
} 

HTML:

<input type="radio" value="1" data-bind="checked:Test" /> 
<input type="radio" value="2" data-bind="checked:Test" /> 
<input type="radio" value="3" data-bind="checked:Test" /> 

默認情況下第二無線輸入被選中。點擊第一個廣播後,第一個和第二個都被選中。

enter image description here

更新: 這是發生在我包括jQuery和淘汰賽。如果刪除jquery然後一切正常。 但它只是測試頁面。在真實的項目中,我需要在某些地方使用jQuery,在這種情況下,我無法刪除它。

Sample。 源測試頁:

<html xmlns="http://www.w3.org/1999/xhtml"> 
    <head> 
     <script type="text/javascript" src="knockout-2.1.0.js"></script> 
     <script type="text/javascript" src="jquery-1.6.4.js"></script> 
     <script type="text/javascript"> 
      function Model(){ 
       self = this; 
       self.Test = ko.observable(2); 
       self.Test.subscribe(function(){ 
        if (true) { 
        self.Test(2); 
        } 
       }); 
      } 
     </script> 
    </head> 
<body> 
    <input type="radio" value="1" data-bind="checked:Test" /> 
    <input type="radio" value="2" data-bind="checked:Test" /> 
    <input type="radio" value="3" data-bind="checked:Test" /> 
</body> 
<script type='text/javascript'> 
    ko.applyBindings(new Model()); 
</script> 
</html> 
+1

也許你可以基於這個小提琴重現:http://jsfiddle.net/rniemeyer/2uCAF/?我認爲你可能會遇到另一個問題,因爲綁定不會讓你選擇第一個和第二個收音機。你也應該爲你的輸入提供一個通用的'name'屬性,這會保持它們的分組,儘管KO仍然會保持它們同步。 –

+0

是的,添加名稱屬性。 http://www.w3.org/TR/html401/interact/forms.html#radio – mg1075

回答

7

更新(2015-02-27):自Knockout 3.1.0開始,Knockout不包含click事件的任何「解決方法」代碼,並且在處理問題中的示例時應該沒有問題。 http://jsfiddle.net/9S96U/3/


當jQuery是包括在內,敲除使用它來處理事件,包括用於向單選按鈕響應click事件。它包括一些「解決方法」代碼,以確保單擊處理程序看到單選按鈕的正確已選中狀態,但這似乎會干擾試圖重置中間值的代碼。

解決方案是使用setTimeout更新值。這種方式發生在點擊處理程序完成後。

function Model(){ 
    var self = this; 
    self.Test = ko.observable(2); 
    self.Test.subscribe(function(){ 
     setTimeout(function() { 
      self.Test(2); 
     }); 
    }); 
} 

例子:http://jsfiddle.net/9S96U/1/

還需要var之前self = this包括讓你不覆蓋window.self

0

背後訂閱/發佈的想法是,你可以有一個觀測結果發送給多個用戶,誰做自己的測試。

我還沒有實際使用過knockout.js,但是,我已經用委託/異步流/承諾/ etc做了很多工作 - 主要是對特殊情況使用輕量級定製實現。

你的目標是讓一個控制器運行一次測試(你現在得到的),然後遍歷每一個,確保選中了正確的一個(i - 1),並且所有其他的未被檢查...

...或者以更傳統的發佈者/訂閱者的方式,讓一個發佈者(如fieldset可能是所有無線電控制的父元素)監聽其中一個輸入更改,然後通知每個訂閱輸入的值,並讓他們自己做測試。

在僞發言:

var subscribers = []; // array of input "Model" callbacks 
         // (ie: tests to determine whether they're off or on) 

parentElement.listen("click", function (e) { 
     var self = this, 
      selectedRadio = e.target, 
      val = selectedRadio.value; 

     subscribers.forEach(function (notify) { notify(val); }); 
}); 

要處理你目前的情況,你可以使用依賴注入:

new Model(value); 
,你緩存要麼

new Model(subscription_test_for_element); 

預期測試值,或者在每個獨立插件中緩存輸入特定測試/成功/失敗邏輯的位置tance ...

...或者您創建一個更大的控制器(不推薦)來處理每個輸入的硬編碼邏輯。

當然,更具體的幫助,可以給予依據究竟是什麼模型,你怎麼實例,爲什麼你硬編碼您的訂閱進入施工,如果它要成爲通用模型等等。