KO Nested Mapping
HTML
<script src="http://cdnjs.cloudflare.com/ajax/libs/knockout/3.1.0/knockout-debug.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/knockout.mapping/2.4.1/knockout.mapping.js"></script>
<b>Mapped:</b>
<div id="mapped">
<pre data-bind="text: ko.mapping.toJSON($root)">
Pre-Bind
</pre>
<pre id="debug" data-bind=
"text: JSON.stringify(ko.mapping.toJS($root),null,2)" >
</pre>
<!-- ko foreach: $root -->
<pre id="debug" data-bind=
"text: 'DDDD:' + person()" >
</pre>
<pre id="debug" data-bind="text: 'AAAA:' + (person() !== null? person().name():person())">
</pre>
<!-- /ko -->
</div>
<br/>
<input type="button" value="Map 1" id="map1" />
<input type="button" value="Map 2" id="map2" />
CSS
body * {
font-family: Arial, Helvetica;
margin: 0;
padding: 3px;
}
pre {
border: solid 1px #CCC;
background-color: #eee;
font-family: Consolas, Monospace, Courier New;
font-size: 10pt;
}
JavaScript
// Sample value 1: nested object, with person data
var val1 = {
id: 1,
person: {
name: 'Johnie',
surname: 'Walker'
}
};
// Sample value 2: nested object, with null person
var val2 = {
id: 2,
person: null
};
var arr = [];
arr.push(val1);
//arr.push(val2);
// Constructor for Person vm
var Person = function() {
var self = this;
self.Name = ko.observable();
self.Surname = ko.observable();
return self;
};
// mapping: called when person property is created
// it's called on every call to mapping.fromJS
var mapping = {
person: {
create: function(options) {
//var person = new Person();
if (!options.data)
return ko.observable(null);
return ko.observable(ko.mapping.fromJS(options.data));
//return new ko.observable(person);
}
}
};
// Creates the first map, based on val1 (with person data)
window.vm = ko.mapping.fromJS(arr, mapping);
ko.applyBindings(vm);
//ko.mapping.fromJS(arr, window.vm);
$('#map1').click(function() {
var x = window.vm()[0];
ko.mapping.fromJS(val1, {}, x);
});
$('#map2').click(function() {
ko.mapping.fromJS(val2, {}, window.vm()[0]);
});