Background
I have a pretty basic application I'm developing as a learning exercise for Knockout. In my view model, I have an observable array of students. This object is comprised of many students, which are my model. Each student has an observable array of scores. The scores array consist of observable numbers that are dynamically pushed to the scores array.
The information above describes my intent. Unfortunately, something's breaking, but I cannot decipher where. My console log shows that the values in my array of scores are not being updated when I push to the array. It is unclear to me where my logic/methodology is wrong. The lack of updating is most clearly seen when I try to update the average score in the scores` array.
My content, as well as console log, can be accessed here: 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
Note that the code below are relevant snippets, not the whole of the application.
1. Model
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. View Model
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));
}
});
};
}
Edit
Just as an added note, I spent a reasonable amount of time looking into this at SO but none of the solutions I encountered where helpful for me so far.