我正在尝试构建成绩簿应用程序,主要是作为学习练习。目前,我有两个模特,一个学生,一个作业。我决定将所有与分数相关的信息存储在学生中,而不是每个作业。也许有更好的方法。
无论如何,我已经获得了每个学生的平均分数,即她在课堂上的成绩。我现在正想要计算每项任务的平均分数。这是我遇到麻烦的地方,因为它有点棘手。我目前正在使用以下方法:
JS Bin (整个项目):http://jsbin.com/fehoq/84/edit
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);
});
我将以下列方式将其绑定到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
并将其绑定到较低的foreach: assignments
,它会一直返回-1
(每项任务)。
Knockout文档告诉我,当我打电话给indexOf
时,这意味着没有匹配,但我为什么会迷失方向。指导赞赏。
答案 0 :(得分:3)
除了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>
与正常函数绑定,而不是可观察函数。那么为什么这仍然有用?
RP Niemeyer, one of the Knockout core members writes:
在Knockout中,绑定是使用dependentObservables在内部实现的,因此您实际上可以使用普通函数代替绑定中的dependentObservable。绑定将在dependentObservable中运行您的函数,因此任何访问其值的observable都将创建一个依赖项(您的绑定将在更改时再次触发)。
(曾经被称为计算的observables&#34; dependentObservables&#34;在早期版本的Knockout中)
对于这些类型的问题,熟悉调试器(例如Chrome Developer Tools中的调试器)确实很有帮助。能够逐行浏览代码并查看实际包含的参数和变量非常有用。
在调试绑定时,Chrome Knockout context debugger值得拥有,因为您可以单击任何DOM元素并查看绑定上下文:
最后,在控制台中使用ko.dataFor()
可以让您查看绑定到DOM的任何现有Knockout模型和视图模型:
在Chrome控制台中,$0
始终是对您当前在“元素”面板中选择的DOM元素的引用 - 此处为<td>
。