Testing ko,mapping.JS 2.3.2

by gene

HTML

<script src="https://raw.github.com/SteveSanderson/knockout/master/build/output/knockout-latest.debug.js"></script>
<script src="https://raw.github.com/SteveSanderson/knockout.mapping/master/build/output/knockout.mapping-latest.debug.js"></script>
<html>
    <body>
        <div data-bind="foreach: sortedTitles">
            <div data-bind="click: $root.selectedTitle, css: {'selected': selected()}"><span data-bind="text: title"></span> [<span data-bind="text: count"></span>]</div>
        </div>

        <button data-bind="click: loadMore">Load more</button>
        <div>Selected: <span data-bind="text: selectedTitle"></span></div>
    </body>
</html>

CSS

.selected {
    font-weight: bold;
}

body {
    font-family: sans-serif;
}

JavaScript

function Foo(data, model) {
    var self = this;

    this.viewModel = model;

    this.id = ko.observable(data.id);
    this.title = ko.observable(data.title);
    this.count = ko.observable(data.count);

    this.selected = ko.computed(function() {
        return self.viewModel != null && self.viewModel.selectedTitle() == self;
    });

this.toString = function() { return self.title() + ' [' + self.count() + ']' };
};

function ViewModel() {
    var self = this;
    
    this.titles = ko.observableArray([]);
    
    this.sortedTitles = ko.computed(function() {
        var list = self.titles().slice(0);
        list.sort(function(a, b) {
            return b.count() - a.count();
        });
        return list;
    });
    ko.utils.extend(this.sortedTitles, ko.observableArray.fn);

    this.selectedTitle = ko.observable();
    
    var mapping = {
        ignore: ['sortedTitles', 'selectedTitle'],
        titles: {
            key: function(data) { return ko.utils.unwrapObservable(data.id); },
            create: function(options) { return new Foo(options.data, self); }
        }
    };
    
    this.load = function(data) {
         ko.mapping.fromJS(data, mapping, self);
    };
    
    this.loadMore = function() {
        self.load(data2);
    };    
};

var model = new ViewModel();
    

ko.applyBindings(model);

var data1 = {titles: [{'id': 1, 'title': 'one', 'count': 1}, 
                      {'id': 2, 'title': 'two', 'count': 27},
                      {'id': 3, 'title': 'three', 'count': 5}]};

var data2 = {titles: [{'id': 1, 'title': 'one', 'count': 1}, 
                      {'id': 2, 'title': 'two', 'count': 10},
                      {'id': 3, 'title': 'three', 'count': 50},
                      {'id': 4, 'title': 'four', 'count': 20}]};            
model.load(data1);