I have the following snippet JQuery inside an HTML file:
$.getJSON("/events/", function (data) {
viewModel = ko.mapping.fromJS(data);
ko.applyBindings(viewModel);
});
The code is executed when, for example, the user presses a button and returns JSON like:
{"Events":[{"Name":"Event1"},{"Name":"Event2"},{"Name":"Event3"}]}
This result is linked (using KnockoutJS) to:
<ul data-bind="foreach: Events">
<li><span data-bind="text: Name"></span></li>
</ul>
Everything works fine with the first call to $.GetJSON
. I get what I want, which is (browser output):
But in subsequent calls to "$. GetJSON" I get the following error in Firebug:
NotFoundError: Node was not found.
containerNode.insertBefore(nodeToInsert, insertAfterNode.nextSibling);
And I get no list item.
What I can be doing wrong?
Thank you very much in advance.
The whole point of Knockout is to handle the interaction between your view and view model. In this case, you're trying to update a list of events in response to a button click. The button click should be linked to a function in your view model, while the list should be linked to an observable array that's updated when you click the button. I've put this together in a fiddle here: http://jsfiddle.net/mbest/uZb3e/ and the important parts are below:
<button type=button data-bind="click: updateEvents">Update</button>
<ul data-bind="foreach: data.Events">
<li><span data-bind="text: Name"></span></li>
</ul>
Javascript:
var viewModel = {
data: ko.mapping.fromJS({"Events":[]}),
updateEvents: function() {
var self = this;
$.getJSON("/events/", function (data) {
ko.mapping.fromJS(newData, self.data);
});
}
};
ko.applyBindings(viewModel);
My friend Thomas Brattli found the solution:
<ul data-bind="template: { name: 'template', foreach: Events }"></ul>
<script id="template" type="text/html">
<li><span data-bind="text: Name"></span></li>
</script>
Thanks !