Backbone.LinkedCollection

Smarter Backbone Collection object utilising Web Linking (RFC5988). This demo uses Github API.

HTML

<script src="http://underscorejs.org/underscore-min.js"></script>
<script src="http://backbonejs.org/backbone-min.js"></script>
<script src="https://github.com/downloads/wycats/handlebars.js/handlebars-1.0.0.beta.6.js"></script>
<script src="https://raw.github.com/hongymagic/Backbone.LinkedCollection/master/lib/RFC5988.js"></script>
<script src="https://github.com/hongymagic/Backbone.LinkedCollection/raw/master/src/Backbone.LinkedCollection.js"></script>
<div class="container">
    <h1>Public Gists</h1>
    <ul id="gists"></ul>
    <nav role="pager">
        <a href="#next" rel="next">Load more</a>
    </nav>
</div>

<script id="template-gist" type="html/template">
    <li data-id="{{id}}">
        <a href="{{html_url}}">
            {{#if description}}
                {{description}}
            {{else}}
            <span class="noname">Untitled</span>
            {{/if}}
        </a> 
        <small>by <a href="{{user.url}}">{{user.login}}</a></small>
    </li>
</script>

CSS

html, body { font: 16px/140% Palatino, Georgia, 'Times New Roman', serif; }
body, ul { margin: 0; padding: 0; }

a { color: #222; }
a, a:hover, a:active, a:focus, a:visited { text-decoration: none; }

h1 { margin: 10px 0; font-weight: 300; }
small { font-size: 80%; }
small, .noname { color: #bbb; }

ul { margin: 25px 0; border-top: 1px solid #000; border-bottom: 1px solid #000; padding: 25px 0; list-style: none; }
li { padding: 4px 0 4px 20px; width: 100%; box-sizing: border-box; text-overflow: ellipsis; overflow: hidden; white-space: nowrap; background: transparent url(https://a248.e.akamai.net/assets.github.com/images/gist/gist/paste.png) no-repeat left 4px; line-height: 16px; }

.container { margin: 0 auto; padding: 10px; width: 90%; box-sizing: border-box; }
[role=pager] a { display: block; text-align: center; }

JavaScript

// Namespacing for this Demo app
var Demo = Object.create(null);
Demo.Models = {};
Demo.Collections = {};
Demo.Views = {};
Demo.Utils = {};

/**
 * Gist model provided by Github API
 *
 * http://developer.github.com/v3/gists/#get-a-single-gist
 */
Demo.Models.Gist = Backbone.Model.extend({
    urlRoot: 'https://api.github.com/gists'
});

/**
 * Collection of gists
 *
 * http://developer.github.com/v3/gists
 */
Demo.Collections.Gists = Backbone.LinkedCollection.extend({
    url: 'https://api.github.com/gists/public',
    model: Demo.Models.Gist
});

/**
 * Utility to grab HTML template. It is extremely inefficient.
 */
Demo.Utils.TemplateHelper = {
    compile: function(id, model) {
        var html = $('#' + id).html() || '';
        var template = Handlebars.compile(html);
        return template(model);
    },

    template: function(id) {
        var html = $('#' + id).html() || '';
        return Handlebars.compile(html);
    }
};

/**
 * Backbone.Events based global pub/sub
 */
Demo.Utils.Bus = _.clone(Backbone.Events);

/**
 * Single gist view
 */
Demo.Views.Gist = Backbone.View.extend({
    template: Demo.Utils.TemplateHelper.template('template-gist'),

    render: function() {
        this.$el.html(this.template(this.model.toJSON()));
        return this;
    }
});

/**
 * Simple Gist list view
 */
Demo.Views.GistList = Backbone.View.extend({
    initialize: function() {
        this.model.on('reset', this.refresh, this);
        this.model.on('add', this.addGist, this);
        return this.render();
    },

    render: function() {
        return this;
    },

    refresh: function() {
        var html = '';
        this.model.each(function (gist) {
            html += (new Demo.Views.Gist({ model: gist }).render()).$el.html();
        });
        
        this.$el.html(html);
    },
    
    addGist: function(gist) {
        var html = (new Demo.Views.Gist({ model: gist }).render()).$el.html();
        this.$el.append(html);
    }
});

Demo.Views.Demo =...