Knockout.js mapping JSON object to Javascript Object

http://stackoverflow.com/questions/8805548/knockout-js-mapping-json-object-to-javascript-object

by rniemeyer

HTML

<script src="http://knockoutjs.com/downloads/knockout-2.0.0.debug.js"></script>
<p>First name: <input data-bind="value: FirstName" /></p>
<p>Last name: <input data-bind="value: LastName" /></p>
<p>Full name: <span data-bind="text: FullName" ></span></p>
<p>#Friends: <span data-bind="text: Friends().length"></span></p>

<p><button data-bind="click: AddFriend, enable:Friends().length < 5" >add new friend</button></p>

<br/>

<table data-bind="foreach: Friends">
    <tr>
        <td>First name: <input data-bind="value: FirstName" /></td>
        <td>Last name: <input data-bind="value: LastName" /></td>
        <td>Full name: <span data-bind="text: FullName" ></span></td> 
        <td><button data-bind="click: $parent.DeleteFriend">delete</button></td> 
    </tr>
</table>

JavaScript

function Person(FirstName, LastName, Friends) {
    var self = this;
    self.FirstName = ko.observable(FirstName);
    self.LastName = ko.observable(LastName);
    self.FullName = ko.computed(function() {
        return self.FirstName() + ' ' + self.LastName();
    });

    self.Friends = ko.observableArray(ko.utils.arrayMap(Friends, function(friend) {
        return new Person(friend.FirstName, friend.LastName);
    }));


    self.AddFriend = function() {
        self.Friends.push(new Person('new', 'friend'));
    };
    self.DeleteFriend = function(friend) {
        self.Friends.remove(friend);
    };
}

var viewModel;


var dataFromServer = {
    FirstName: "Bob",
    LastName: "Smith",
    Friends: [{
        FirstName: "Ted",
        LastName: "Jones"}]
};

setTimeout(function() {
    var dataFromServer = {
        FirstName: "Bob",
        LastName: "Smith",
        Friends: [{
            FirstName: "Ted",
            LastName: "Jones"}]
    };
    
    viewModel = new Person(dataFromServer.FirstName, dataFromServer.LastName, dataFromServer.Friends);

    ko.applyBindings(viewModel);
}, 500);