"Latest" Base Fiddle

Latest copy of: -jQuery templates -KnockoutJS -KO Mapping plugin

HTML

<script src="http://cloud.github.com/downloads/SteveSanderson/knockout/knockout-2.1.0.js"></script>
<script src="https://raw.github.com/SteveSanderson/knockout.mapping/master/build/output/knockout.mapping-latest.js"></script>
<script src="https://github.com/jquery/jquery-tmpl/raw/master/jquery.tmpl.js"></script>
<div data-bind="text: fullName"></div>

<ul data-bind="foreach: children">
    <li data-bind="text: description"></li>
</ul>

JavaScript

var viewModel = {};
var data = {
    id: "1",
    firstName: 'Adam',
    lastName: "Smith",
    children: [ {id: "2", name: "Bob", age: 5}, {id: "3", name: "Chris", age: 7 }]
};

var childMapping = {
    create: function (options){    
        var innerModel = ko.mapping.fromJS(options.data);
        innerModel.description = ko.computed(function() {
            return innerModel.name() + ' is ' + innerModel.age() + ' years old';
        }, this);
        
        return innerModel;
    },
    key: function(data) { return ko.utils.unwrapObservable(data.id); }    
}

var parentMapping = {
    create: function (options){
        var innerModel = ko.mapping.fromJS(options.data);
        
        innerModel.fullName = ko.computed(function() {
            return innerModel.firstName() + ' ' + innerModel.lastName();
        }, this);
                
        return innerModel;
    },
    'children': {
        create: function(options) { 
            return ko.mapping.fromJS(options.data, childMapping); 
        }
    },
    key: function(data) { return ko.utils.unwrapObservable(data.id); }    
};

viewModel = ko.mapping.fromJS(data, parentMapping);
ko.applyBindings(viewModel);