I'm trying to reimplement a student attendance example from the Udacity JavaScript Design Patterns course. So far I've managed to recreate the table and correctly populate it with some student data, however it appears when I change a checkbox value this isn't updated in the model.
For example, when I display
debugVM.studentList()[0].days();
in the console the output displays the initial attendance data instead of the current state of the checkboxes. A JSFiddle for this can be found here.
index.html
<table>
<thead>
<tr>
<th>Student</th>
<!-- ko foreach: attendance -->
<th data-bind="html: $data"></th>
<!-- /ko -->
</tr>
</thead>
<tbody data-bind="foreach: studentList">
<tr>
<td data-bind="html: name, click: $parent.debugStudent"></td>
<!-- ko foreach: days -->
<td>
<input type="checkbox" data-bind="value: $data, checkedValue: $data, checked: $data" />
</td>
<!-- /ko -->
</tr>
</tbody>
</table>
app.js
var Student = function(student){
this.name = ko.observable(student.name);
this.days = ko.observableArray(student.days);
};
var ViewModel = function() {
var self = this;
this.attendance = ko.observableArray([1,2,3,4,5,6,7,8,9,10,11,12]);
this.studentList = ko.observableArray([]);
students.forEach(function(student) {
self.studentList.push(new Student(student));
});
self.debugStudent = function() {
console.log(self.studentList()[0].days());
};
};
var debugVM = new ViewModel();
ko.applyBindings(debugVM);
From the knockout documentation
Key point: An observableArray tracks which objects are in the array, not the state of those objects
In your case this means that days
should be not observable array, but array of observables.
For example you can add new viewModel Day
:
var Day = function(isChecked) {
this.isChecked = ko.observable(isChecked);
}
And set the days
property like this
this.days = [];
for (var i = 0; i< student.days.length; i++) {
this.days.push(new Day(student.days[i] == 1));
}
See working fiddle