javascript - knockout JS : indexOf always returns -1?

标签 javascript html knockout.js indexof ko.observablearray

背景

我正在尝试构建一个成绩簿应用程序,主要作为学习练习。目前,我有两个模型、一个学生和一个作业。我决定将所有与分数相关的信息存储在学生内部,而不是存储在每个作业中。也许有更好的方法。

无论如何,我已经有了每个学生的平均分,即她在类的成绩。我现在想要计算每项作业的平均分数。这就是我遇到麻烦的地方,因为它有点棘手。我目前正在使用以下方法:

JS Bin (entire project): http://jsbin.com/fehoq/84/edit

JS

  var _this = this;
  ...

  // get index i of current assignment; 
  // then, for each student, grab her grade for assignment i;
  // add each grade at i, then divide by # of students;
  // return this value (the mean);

  this.workMean = ko.computed(function (work) {
        var i = parseFloat(_this.assignments.indexOf(work)); 
        var m = 0;
        var count = 0;
        ko.utils.arrayForEach(_this.students(), function (student) {
            if (!isNaN(parseFloat(student.scores()[i]))) {
                m += parseFloat(student.scores()[i]);
            } else {
                count += 1;
            }
        });
        m = m / (_this.students().length - count); 
        return m.toFixed(2);   
    });

我通过以下方式将其绑定(bind)到 HTML:

HTML

<tbody>
  <!-- ko foreach: students -->
    <tr>
        <td><input data-bind="value: fullName + ' ' + ($index()+1)"/></td>  
        <!-- ko foreach: scores -->  
        <td><input data-bind="value: $rawData"/></td>
        <!-- /ko --> 
        <td data-bind="text: mean" />
        <td><input type="button" value="remove" data-bind="click: $root.removeStudent.bind($root)". /></td>
    </tr> 
  <!-- /ko -->
    <tr>
      <td>Class Work Average</td> 
      <!-- ko foreach: assignments -->
      <td data-bind="text: $root.workMean"></td>
      <!-- /ko -->
    </tr>  
</tbody>    

问题是我在这里所做的事情 - 我认为是 workMean() 方法 - 完全破坏了我的应用程序。在尝试调试时,我注意到,如果我简单地注释掉整个方法 save i,然后返回 i 并将其绑定(bind)到较低的 foreach: assignments,它始终返回 -1(对于每个分配)。

Knockout 文档告诉我,这意味着当我调用 indexOf 时没有匹配项,但我不知道为什么。感谢指导。

最佳答案

除了 DCoder identified 的问题- observables 不接受参数 -,你在这里还有另一个错误:

score = parseFloat(student.scores()[i]);

应该是

score = parseFloat(student.scores()[i]());

您访问的可观察数组的第 n 个(或第 i 个)元素本身就是一个可观察的,因此在此之前,您将函数传递给 parseFloat ,它总是产生 NaN。

这是一个工作版本:http://jsbin.com/lejezuhe/3/edit

顺便说一句:DCoders 更改后,

<td data-bind="text: $root.workMean($data, $index())"></td>

绑定(bind)一个普通函数,而不是一个可观察的函数。那么为什么这仍然有效?

RP Niemeyer, one of the Knockout core members writes :

In Knockout, bindings are implemented internally using dependentObservables, so you can actually use a plain function in place of a dependentObservable in your bindings. The binding will run your function inside of a dependentObservable, so any observables that have their value accessed will create a dependency (your binding will fire again when it changes).

(在早期版本的 Knockout 中,计算的可观察量过去称为“dependentObservables”)

对于这些类型的问题,熟悉调试器(例如 Chrome Developer Tools 中的调试器)确实很有帮助。 。能够逐行单步执行代码并查看实际包含的参数和变量非常有帮助。

Chrome Knockout context debugger在调试绑定(bind)时值得拥有,因为您可以单击任何 DOM 元素并查看绑定(bind)上下文:

Screenshot depicting the Knockout context debugger in action

最后,使用 ko.dataFor()控制台中的 允许您查看绑定(bind)到 DOM 的任何现有 Knockout 模型和 View 模型:

Screenshot depicting the usage of ko.dataFor() in the dev tools console

在 Chrome 控制台中,$0始终是对您当前在“元素”面板中选择的 DOM 元素的引用 - 这里是 <td> .

关于javascript - knockout JS : indexOf always returns -1?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23299194/

相关文章:

jquery - Chrome 所需的 Bootstrap 自动完成滚动条

asp.net-mvc - 如何使用 knockout 自定义绑定(bind)获取 jquery 验证状态?

javascript - 使用沙盒帐户时出现 API 错误

javascript - 我必须在 Javascript 中使用 HMAC sha256 对文本进行哈希处理

javascript - React 网站如何被搜索引擎索引?

javascript - AngularJS 过滤器唯一删除 ng-options 中的重复项

html - 为什么 HTML 中的属性 "fdprocessedid"出现在控制台中?

knockout.js - 有没有办法避免敲击时的提交绑定(bind)在按下回车键时发送表单?

javascript - knockout 绑定(bind)到单选框

javascript - Mustache.js不会刷新缓存