KO infinite append test

by whelkaholism

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.11.2/jquery-ui.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.11.2/jquery-ui.min.css">
<script src="//cdnjs.cloudflare.com/ajax/libs/knockout/3.3.0/knockout-min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/knockout.mapping/2.4.1/knockout.mapping.js"></script>
<button data-bind="click: addMore">Add more</button>
<ul id="list" data-bind="foreach: Events">
    <li>
        <span data-bind="text: Caption"></span>
        <span data-bind="text: X"></span>
    </li>
</ul>

JavaScript

function EventModel(data, mapping)
{
    var _this = this;
    
    if(data)
        ko.mapping.fromJS(data, mapping, _this);
    
    this.ID = this.ID || ko.observable();
    this.Caption = this.Caption || ko.observable();
    
    this.X = ko.computed(function() { return 'X'; });
}

function RootModel(data, mapping)
{
    var _this = this;
    var _mapping = mapping || {
        'Events': { 
            key: function(data) { return ko.unwrap(data.ID);  },
            create: function(options) {  return new EventModel(options.data); }
        }
    };

    var _id = 1;    
    
    if(data)
        ko.mapping.fromJS(data, _mapping, _this);
    
    this.Events = ko.observableArray();
    
    // 
    this.addMore = function(model, e)
    {
        _this.getMore({ 
            success: 
                function(data) 
                { 
                    _this.Events.push.apply(_this.Events, ko.utils.arrayMap(data, 
                        function(o)
                        {
                            return new EventModel(o, _mapping);
                        }
                    ));
                }
        });
    };
    
    this.getMore = function(getoptions)
    {
        var res = [];
        
        for(var i = 0; i < 10; i++)
        {
            res.push({ ID: _id, Caption: 'Item ' + _id });
            
            _id++;
        }
        
        $.ajax({
            url:'/echo/json/',
            dataType: 'json',
            type: 'POST',
            data: 'json=' + ko.toJSON({ Data: res }) + '&delay=' + Math.random() * 3,
            success: 
                function(data, status, jqxhr)
                {                    
                    getoptions.success && getoptions.success(data.Data);
                }
        });
    };
}

ko.applyBindings(new RootModel());