Prevent tab contents from loading multiple times (

2019-05-20 23:02发布

I have a few tabs on my page, whose contents (consisting of many SetView contained by SetListView) are loaded using Backbone.js whenever its tabs is being clicked on.

Problem:: When the user switches from a tab to a previously loaded/viewed tabbed, the contents load again and append to the previously loaded content in SetListView. I can get it to clear the previously loaded contents before loading it again, but it seems to be less than optimal to keep loading the same content.

Is it possible to make Backbone.js store existing content for a tab and not load it multiple times when switching back to the same tab?

Views

// Views

var SetListView = Backbone.View.extend({
    el: '#set_list',

    initialize: function() {
        this.collection.bind('reset', this.render, this);
    },

    render: function() {
        this.collection.each(function(set, index) {
            $(this.el).append( new SetView({ model: set }).render().el );
        }, this);
        return this;
    }
});

var SetView = Backbone.View.extend({
    tagName: 'div',
    className: 'photo_box',

    template: _.template( $('#tpl_SetView').html() ),

    initialize: function() {
        this.model.on('destroy', this.close, this);
    },

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

    close: function() {
        this.unbind();
        this.remove();
    }
});

Router

// Router

var AppRouter = Backbone.Router.extend({

    routes: {
        '': 'sets',
        'sets': 'sets'
    },

    viewing_user_id: $('#viewing_user_id').val(),

    sets: function() {
        this.showTab('sets');

        this.setList = new SetCollection();
        this.setListView = new SetListView({ collection: this.setList });
        var self = this;
        this.setList.fetch({
            data: {user_id: self.viewing_user_id},
            processData: true
        });
    },

    showTab: function(tab) {
        // Show/hide tab contents
        $('.tab-content').children().not('#tab_pane_' + tab).hide();
        $('.tab-content').children('#tab_pane_' + tab).fadeIn('fast');

        // Activate/deactivate tabs
        $('#tab_' + tab).addClass('active');
        $('#tab_' + tab).siblings().removeClass('active');
    }
});

1条回答
小情绪 Triste *
2楼-- · 2019-05-20 23:24

Backbone has not any in-house system to difference between when you want to re-fetch the content or re-using the already fetched one. You have to decide when do each of this actions.

A modification of your example code to achieve this can be:

var AppRouter = Backbone.Router.extend({
    // ... more router code

    sets: function() {
        if( !this.setList ) this.initializeSets();
        this.showTab('sets');
    },

    initializeSets: function(){
        this.setList = new SetCollection();
        this.setListView = new SetListView({ collection: this.setList });
        var self = this;
        this.setList.fetch({
            data: {user_id: self.viewing_user_id},
            processData: true
        });
    },
});

So you only call initializeSets() if they are not already initialized. Of course will be more elegant and clean ways to ask if the sets have been initialized but this is up to you.

查看更多
登录 后发表回答