2010-12-13 76 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