ObservableArray不反映数据更新

Ale*_*lex 5 javascript knockout.js

我正在使用非常光滑的KnockoutJS库创建一个应用程序,但我遇到了麻烦.在html页面上,我有一个简单的<select>控件,我想加载从Web服务返回的JSON数据.

我定义了可观察数组,如下所示:

var laborRow = function () {
    this.positions = ko.observableArray([]);
};
Run Code Online (Sandbox Code Playgroud)

页面加载时,将进行ajax调用并返回数据.在回调中,我执行以下操作:

    success: function (msg) {
        laborRow.positions = msg;
    }
Run Code Online (Sandbox Code Playgroud)

基于KO文档,我希望我会将结果设置为:

laborRow.positions(msg);
Run Code Online (Sandbox Code Playgroud)

但是,这只是抛出一个错误,指出"laborRow.positions in not a function"

html中的模板如下:

<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>
Run Code Online (Sandbox Code Playgroud)

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**
            },
Run Code Online (Sandbox Code Playgroud)

和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> 
Run Code Online (Sandbox Code Playgroud)

最后,感谢Sean在下面的评论,我能够通过修改回调中的代码来实现它,如下所示:

success: function (msg) {
    projectViewModel.laborLine()[(projectViewModel.laborLine().length-1)].positionList(msg);
}
Run Code Online (Sandbox Code Playgroud)

Sea*_*ira 5

问题是你还没有真正创建你的模型:

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

将您的函数更改为裸对象(如Knockout文档中所示):

var laborRow = {
    positions: ko.observableArray([])
};
Run Code Online (Sandbox Code Playgroud)

而且你将能够打电话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
Run Code Online (Sandbox Code Playgroud)

我曾经多次被"ko变量getters不是attributes"错误所困扰......你的代码可能会发生这种情况吗?