Search code examples
backbone.jsunderscore.js

re-render Backbone view with new models


Basically, I would like to render a random list of headlines from collection, and then re-render the list with a different set of headlines whenever a user triggers the "loadMore" headlines event.

I have a StoryList view that appends a new StoryListItem view for each model in my collection. I am also using the underscore method sample() to randomize and limit the number of models, and therefore the number of StoryListItem views that are rendered. Lastly, I have an event delegated to this view called "loadMore." I would like the loadMore event to re-render the view with a different sample from the original collection.

Currently, the loadMore event basically reconstitutes the original collection (the sampled model contains the attribute "models" which contains all of models that we're originally sampled), and then re-renders the view. The result is a second view element appended after the original view element. I just know that I'm not going about this the right way, and I'm hoping someone can set me on the right track.

sbk.StoryListView = Backbone.View.extend({
        tagName: 'ul',
        id: 'story-list',
        initialize: function () {
            this.collection.on('reset', this.render, this);
            console.log('initialize');
        },
        template: Handlebars.compile($('#story-list-template').html()),
        render: function () {
            var newCollection = _.sample(this.collection.models, 4);
            _.each(newCollection, function (storyItem) {
                $(this.el).append(new sbk.StoryListItemView({model: storyItem}).render().el);
            }, this);

            $(this.el).append(this.template());
            return this;
        },
        events: {
            'click #load-more' : 'loadMore'
        },
        loadMore: function(){
            this.collection = new Backbone.Collection(this.collection.models);
            this.render();
        }
    });

Solution

  • Instead of appending, simply replace the html of the view element.

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