2010-12-13 105 views
5

我使用非常漂亮的KnockoutJS庫創建了一個應用程序,但我碰到了一個障礙。在html頁面上,我有一個普通的<select>控件,我想用從Web服務返回的JSON數據加載。ObservableArray沒有反映數據更新

我定義如下觀察到的數組:

var laborRow = function() { 
    this.positions = ko.observableArray([]); 
}; 

頁面加載,Ajax調用是由並返回數據。在回調,我做到以下幾點:

success: function (msg) { 
     laborRow.positions = msg; 
    } 

基礎上KO文檔,我希望我會設置的結果是這樣的:

laborRow.positions(msg); 

然而,這只是拋出一個錯誤,指出

在HTML模板如下 「中沒有的功能laborRow.positions」:

<tbody data-bind='template: {name: "laborRowTemplate", foreach: laborLine}'> </tbody> 
</div> 
    <script type="text/html" id="laborRowTemplate"> 
     <tr> 

      <td><select data-bind='options: positions, optionsText: "Title", optionsCaption: "select", value: selectedPosition '></select></td> 

     </tr> 
    </script> 

laborRow對象是綁定到頁面的ViewModel上的一個屬性。無論出於何種原因,這都行不通。要添加另一個皺紋,如果我添加代碼以查看observableArray並打印出一些數據,數據就在那裏。所以它正在成功加載。

任何想法將不勝感激。

我的例子情況下的全碼:

var laborRow = function() { 
    this.positions = ko.observableArray([]);  
}; 

var projectEstimate = function() { 
    this.laborLine = ko.observableArray([new laborRow()]); 

}; 

var projectViewModel = new projectEstimate(); 
ko.applyBindings(projectViewModel); 

//and the code in the callback function on ajax success 

success: function (msg) { 
       laborRow.positions = msg; 
       //laborRow.positions(msg); **this does not work - error is laborRow.positions is not a function** 
      }, 

和HTML:

<tbody data-bind='template: {name: "laborRowTemplate", foreach: 
laborLine}'> </tbody> 

    <script type="text/html" id="laborRowTemplate"> 
     <tr> 
      <td><select data-bind='options: positions, optionsText: 
"Title", optionsCaption: "select", value: selectedPosition '></ 
select></td> 

     </tr> 
    </script> 

最後,感謝以下肖恩的意見,我能得到它的工作通過修改代碼回調如下:

success: function (msg) { 
    projectViewModel.laborLine()[(projectViewModel.laborLine().length-1)].positionList(msg); 
} 

回答

5

的問題是,你還沒有真正建立你的模型:

var laborRow = function() { 
    this.positions = ko.observableArray([]); 
    // will only be called if you call var some_var = new laborRow() 
}; 

的功能更改爲裸露的對象(如圖所示Knockout docs):

var laborRow = { 
    positions: ko.observableArray([]) 
}; 

你就可以打電話laborRow.positions(msg);就了事。


編輯

基於新的代碼,laborRow仍然沒有實例化 - 如果你在你的代碼中設置var laborRow別的地方(約Ajax請求,可能),那麼你會希望以確保您的調用堆棧看起來是這樣的:

projectViewModel.laborLine()[0].positions() 
// This will return the array you're looking for. 
// The key is that laborLine is a `getter` not an attribute 

我一直被咬「KO變量gettersattributes」多次錯誤...可能會發生在您的代碼中?

+0

感謝您的迴應肖恩。我創建了這個模型。在實際的viewModel中,我有一個observableArray,它在創建時使用一個新的laborRow對象開始生活,如下所示:this.laborLine = ko.observableArray([new laborRow()]); – Alex 2010-12-14 02:56:20

+0

@亞歷山大 - 優秀...你可以發佈多一點你的代碼嗎?正如你所描述的那樣,目前所有的東西都應該工作。 – 2010-12-14 05:29:00

+0

@Alex - 更新了答案,以便再次刺穿它。 – 2010-12-14 19:19:09