Knockout JS:Observable Array没有更新,无法确定原因

时间:2014-04-20 16:52:49

标签: javascript html knockout.js ko.observablearray

背景

我有一个非常基本的应用程序,我正在开发作为Knockout的学习练习。在我的视图模型中,我有一个可观察的students数组。这个对象由许多student组成,这是我的模型。每个学生都有一个可观察的scores阵列。 scores数组由可观察的数字组成,这些数字被动态推送到scores数组。

以上信息描述了我的意图。不幸的是,有些东西正在破裂,但我无法破译到哪里。我的控制台日志显示,当我推送到阵列时,我的分数数组中的值 not 正在更新。我不清楚我的逻辑/方法在哪里是错误的。当我尝试更新score`数组中的平均分数时,最清楚地看到缺少更新。

我的内容以及控制台日志可在此处访问:http://jsbin.com/fehoq/45/edit

HTML

<button data-bind="click: addWork">Add New Assignment</button>
<table>
    <thead>
        <tr>
            <th>Name</th>
            <!-- ko foreach: assignments -->
            <th><input data-bind="value: workName  + ' ' + ($index() + 1)"/></th>
            <!-- /ko -->
            <!--<th data-bind=>Overall Grade</th> -->
            <th>Class Grade</th>
        </tr>    
    </thead>
    <tbody data-bind="foreach: students">
        <tr>
          <td><input data-bind="value: fullName"/></td>  
            <!-- ko foreach: scores -->  
            <td><input data-bind="value: $data"/></td>
            <!-- /ko --> 
            <td><input data-bind="value: mean" /></td>
            <td><input type="button" value="remove" data-bind="click: $root.removeStudent.bind($root)". /></td>
        </tr>    
    </tbody>    
</table>

JS

请注意,下面的代码是相关的代码段,而不是整个应用程序。

1。模型

var StudentModel = (function () {
    function StudentModel(fullName) {
        var _this = this;
        this.fullName = fullName;
        this.scores = ko.observableArray();
        this.mean = ko.computed(function (scores) {
            var n = 0;
            ko.utils.arrayForEach(_this.scores(), function (score) {
                n += score();
                console.log(n);
            });
            n = n / _this.scores().length;
            return n;
        });
    }

...

2。查看模型

function StudentsViewModel() {
    var _this = this;
    this.students = ko.observableArray([
        new Gradebook.Model.StudentModel("Jeff Smith"),
        new Gradebook.Model.StudentModel("Gandalf")
    ]);
    this.assignments = ko.observableArray([
        new Gradebook.Model.WorkModel("Math"),
        new Gradebook.Model.WorkModel("Reading")
    ]);
    this.addStudent = function () {
        this.students.push(new Gradebook.Model.StudentModel(""));
        this.updateRows();
    };
    this.addWork = function () {
        this.assignments.push(new Gradebook.Model.WorkModel("Assignment "));
        this.updateRows();
    };
    this.updateRows = function () {
        ko.utils.arrayForEach(_this.students(), function (student) {
            while (student.scores().length < _this.assignments().length) {
                student.scores.push(ko.observable(100));
            }
        });
    };
}

修改

作为一个补充说明,我花费了大量的时间来研究这个问题,但到目前为止我遇到的任何解决方案都没有。

1 个答案:

答案 0 :(得分:1)

问题是绑定中的value: $data引用了可观察数组条目的展开的,不可观察的,而不是observable本身。

基本上,这使得它成为单向绑定 - 它读取初始状态,然后再也不会更新。

从Knockout 3.0开始,您可以改为使用$rawData

<!-- ko foreach: scores -->  
  <td><input data-bind="value: $rawData"/></td>
<!-- /ko -->

来自 Binding Context 文档:

  

<强> $rawData

     

这是当前上下文中的原始视图模型值。通常这个   将与$ data相同,但如果视图模型提供给Knockout   包含在一个可观察的数据中,$ data将是未包装的视图模型,   和$ rawData本身就是可观察的。

供参考:Knockout.js using value: binding in a foreach over a list of strings - does not update