ko.mapping create function, extend object

http://stackoverflow.com/questions/9779969/ko-mapping-create-function-extend-object

by farina

HTML

<script src="https://github.com/downloads/SteveSanderson/knockout/knockout-2.0.0.debug.js"></script>
<script src="https://raw.github.com/SteveSanderson/knockout.mapping/master/build/output/knockout.mapping-latest.debug.js"></script>
<div data-bind="template: {name: 'dataTemplate', data: people}"></div>

<script id="dataTemplate" type="text/html">
    <div class="mainData" data-bind="text: full()"></div>   
    <div data-bind="template: {name: 'historyTemplate', data: $data.history}"></div>
</script>

<script id="historyTemplate" type="text/html">
    <div class="historyData">
        <div data-bind="text: comment()"></div>
    </div>    
</script>

<button data-bind="click: loadInitialData">Load Initial Data</button><br />
<button data-bind="click: loadUpdatedData">Load Updated Data</button><br />
<button data-bind="click: loadInitialHistoryData">Load Initial History Data</button><br />
<button data-bind="click: loadUpdatedHistoryData">Load Updated History Data</button><br />

CSS

.mainData {border: 1px solid #000;}
.historyData {background: #efefef;}

JavaScript

var data = [
    { id: 0, first: "Not", last: "Updated" },
    { id: 1, first: "Bob", last: "Smith" },
    { id: 2, first: "Jimmy", last: "Jones" },
    { id: 3, first: "Delete", last: "Me" }
];

var updatedData = [
    { id: 0, first: "Not", last: "Updated" },
    { id: 1, first: "Robert", last: "Smith" },
    { id: 2, first: "James", last: "Jones" },
    { id: 4, first: "New", last: "Guy" }
];

var historyData = [
    { id: 0, comment: "Updated" },
    { id: 1, comment: "Smith" },
    { id: 2, comment: "Jones" },
    { id: 3, comment: "Me" }
];

var updatedHistoryData = [
    { id: 0, comment: "Just Updated" },
    { id: 1, comment: "Smithy" },
    { id: 2, comment: "Jonsey" },
    { id: 4, comment: "Guy" }
];

var Person = function(data) {
    this.id = data.id;
    this.first = ko.observable(data.first);
    this.last = ko.observable(data.last);    
    this.full = ko.computed(function() {
        return this.first() + " " + this.last();
    }, this); 
    this.history = ko.observableArray();    
};

var History = function(data) {
    this.id = data.id;
    this.comment = ko.observable(data.comment);    
};

var dataMappingOptions = {
    key: function(data) {
        return data.id;        
    },
    create: function(options) {
        return new Person(options.data);
    }        
};

var historyDataMappingOptions = {
    key: function(data) {
        return data.id;        
    },
    create: function(options) {
        return new History(options.data);
    }        
};

var viewModel = {
    people: ko.mapping.fromJS([]),
    loadInitialData: function() {
        debugger;
        ko.mapping.fromJS(data, dataMappingOptions, viewModel.people); 
    },
    loadUpdatedData: function() {
        ko.mapping.fromJS(updatedData, dataMappingOptions, viewModel.people);
    },        
    loadInitialHistoryData: function(data) {
        ko.mapping.fromJS(historyData, historyDataMappingOptions , data.history); 
    },
    loadUpdatedHistoryData: function(data) {
  ...