0
votes

My server-side api follows a classic results-paging model, e.g.

/api/transactions/ => page 1 (10 items default limit) /api/transactions/?p=2 => page 2

I want to build a infinite-scrolling system with Backbone views.

I already have non-paging collection+views setup. The parent view looks like this:

Backbone.View.extend({

    initialize: function() {

        this.collection = TransactionCollection;
        this.fetch();

        this.listenTo( this.collection, 'reset', this.renderEntries );
        this.listenTo( this.collection, 'add', this.fetch );

        this.rowViews = [];
        this.render();
    },

    fetch: function() { 
        this.collection.fetch({ reset:true });
    },

    render: function() {

        this.$el.html( template() );
        this.renderEntries();

        return this;
    },

    renderEntries: function() {
        this.clearEntryRows();
        this.collection.each(function(item) {
            var row = new TransactionItemView( item );
            this.rowViews.push( row );
            this.$el.find('.entry-list').append( row.render().el );
        }, this);
    },

    clearEntryRows: function() {
        this.rowViews.forEach(function(v) {
            if (v.close) v.close();
        });
        this.rowViews = [];
    },

// ...
}

This is the relevant part of the view code (child views are simple item views, rendering themselves with a template).

The collection is still very basic:

var TransactionCollection = Backbone.Collection.extend({
    model: Transaction,
    url: '/api/transactions'
});

Now it's time to add pagination. I think I'm going to add a button "MORE...", after each renderEntries() call. That button will fetch for the next page (without resetting the collection) and another renderEntries is called. The this.clearEntryRows() will be moved to the reset callback.

My question is: how can I fetch the second page and add models without resetting the collection and intercept just that event, to render next entry pages? I've read something about 'sync' event: in my understanding, 'reset' gets fired only when I fetch with reset:true, 'sync' gets fired every time I fetch the collection, anyway.

So, if this is correct, I can clear entry rows only on reset event and display rows in sync. But how can I display only the newly added (e.g. page 2) rows to my list?

I'm a little confused.

1
In this case I think you may use only add event instead of reset and append new items to the container.Eugene Glova

1 Answers

1
votes
this.collection.fetch({ add: true, remove: false, merge: false, data: {p: 2} });

this allow you to fetch with specified get parameters and only add not existing entries to collection.

In your view:

initialize: function () {
    this.listenTo(this.collection, 'add', handlerForRenderingNewEntries);
} 

To render only new models, you can return them with specified attribute, extra property 'page' for example. Filter them by this attribute and send to rendrer.