I'm trying out a knockout mapping sample and think I'm almost there. I don't seem able to add a new Foo to the viewModel.foos - can anyone see what I've missed here?
var Foo = function (data) {
var self = this;
self.id = data.id;
self.Name = ko.observable(data.Name);
}
var dataMappingOptions = {
key: function(data) {
return data.id;
},
create: function (options) {
return new Foo(options.data);
}
};
var viewModel = {
foos: ko.mapping.fromJS([]),
loadInitialData: function () {
ko.mapping.fromJS(serverData, dataMappingOptions, viewModel.foos);
},
loadUpdatedData: function () {
ko.mapping.fromJS(serverData, dataMappingOptions, viewModel.foos);
}
};
viewModel.addFoo = function () {
viewModel.foos.push(ko.mapping.fromJS(new Foo()));
viewModel.loadUpdatedData();
}
<ul data-bind="template: {name: 'TopTemplate'}"></ul>
<script type="text/html" id="TopTemplate">
<li><span>Result</span>
<ul data-bind=" template: {name: 'FooTemplate' , foreach: foos} " style="list-style-type:circle;margin-left:15px">
</ul>
</li>
<button data-bind='click: addFoo'>Add Foo</button>
</script>
<script type="text/html" id="FooTemplate">
<li><span data-bind='text: Name'></span>
</li>
</script>
Since the original poster is applying observables inside the Foo class members there's no need to apply ko.mapping.fromJS to it. However I've found that when you have a 'raw' json object (with no mappings) that you need to add to an observable array (i.e. you have previously applied ko.mapping.fromJS()), you do actually need to perform ko.mapping.fromJS e.g.
Otherwise your template bindings (if you have any) will complain that "TypeError xxxx is not a function".
You can just push a new Foo to your observableArray directly.
Here is a sample of loading some initial data and then loading some updated data along with a button to add new items on the client side. http://jsfiddle.net/rniemeyer/wRwc4/