Mapping plugin Create callback, and adding new objects to view model
https://groups.google.com/d/topic/knockoutjs/Teiur2dlenA/discussion
by gurkavcu
HTML
<script src="https://github.com/downloads/SteveSanderson/knockout/jquery.tmpl.js"></script>
<script src="http://github.com/downloads/SteveSanderson/knockout/knockout-1.1.2.js"></script>
<script src="https://github.com/SteveSanderson/knockout.mapping/raw/master/build/output/knockout.mapping-latest.js"></script>
<ul data-bind="template: { name: 'itemTmpl', foreach: items }"></ul>
<script id="itemTmpl" type="text/html">
<li>
ID: <input data-bind="value: id" />
Name: <input data-bind="value: name" />
Category: <span data-bind="text: category"></span>
Subcategory: <select data-bind="options: subcategories, value: subcategory"></select>
</li>
</script>
<hr/>
<h2>ko.toJSON</h2>
<div data-bind="text: ko.toJSON(viewModel.items)"></div>
CSS
input { margin: 2px; width: 75px; }
ul { margin-left: 10px; }
JavaScript
var originalData = {
categoryData: [
{ category: "a", subcategories: ["a1", "a2", "a3"]},
{ category: "b", subcategories: ["b1", "b2", "b3"]},
{ category: "c", subcategories: ["c1", "c2", "c3"]}
],
items: [
{ id: 1, name: "One", category: "a", subcategory: "a2"},
{ id: 2, name: "Two", category: "b", subcategory: "b3"},
{ id: 3, name: "Three", category: "c", subcategory: "c1"}
]
};
function Item(item) {
this.id = item.id;
this.name = ko.observable(item.name);
this.category = ko.observable(item.category);
this.subcategory = ko.observable(item.subcategory);
//deferEvaluation, as this is getting created in the mapping plugin and some of our data is not ready
this.subcategories = ko.dependentObservable({
read: function() {
var currentCategory = this.category();
var category = ko.utils.arrayFirst(viewModel.categoryData(), function(data) {
return data.category() === currentCategory;
});
return category ? category.subcategories() : [];
},
deferEvaluation: true,
owner: this
});
}
var options = {
items: {
create: function(options) {
return new Item(options.data);
}
}
}
var viewModel = ko.mapping.fromJS(originalData, options);
ko.applyBindings(viewModel);