I have the following code that binds an HTML table to a list of Person object using knockout:
function PersonModel(person) {
var self = this;
self.id = person.Id;
self.firstName = person.FirstName;
self.surname = person.Surname;
self.email = person.Email;
self.cell = person.Cell;
}
function PersonListModel(personList) {
var self = this;
self.persons = ko.observableArray(personList);
}
function getPersonList() {
$.getJSON("Person/IndexJson", function (allData) {
var mappedPersons = $.map(allData, function (item) { return new PersonModel(item); });
ko.applyBindings(new PersonListModel(mappedPersons), $("#person-list")[0]);
});
}
$(function () {
$("#refresh").click(function() {
getPersonList();
});
getPersonList();
});
The HTML being bound looks like this:
<table>
<tbody id="person-list" data-bind="foreach: persons">
<tr data-bind="attr: { 'data-id': id }, click: $parent.personClicked">
<td data-bind="text: firstName"></td>
<td data-bind="text: surname"></td>
<td data-bind="text: email"></td>
<td data-bind="text: cell"></td>
</tr>
</tbody>
</table>
<a id="refresh" href="#"></a>
My problem is that the table is only properly populated the first time the page loads. On all subsequent ajax calls, triggered by clicking the Refresh link, the table is empty. The same ajax result is returned in all cases, so I suspect I may be missing some knockout call that ‘frees up’ the initial binding to make way for subsequent bindings or something.
You don’t need to do the new modeling inside your ajax routine. Below should solve your problem