简体   繁体   中英

Change page view with Backbone

I've implemented "change page" in my one page application with Backbone.js. However, I'm not sure if my Router should contain so much business logic. Should I consider go with Marionette.js to implement such functionality and make my Router thin? Should I worry about destroying Backbone models and views attached to "previous" active page/view when I change it (in order to avoid memory leaks) or it's enough to empty html attached to those models/views. Here is my Router:

App.Router = Backbone.Router.extend({
    routes: {
        'users(/:user_id)' : 'users',
        'dashboard' : 'dashboard'
    },
    dashboard: function() {
        App.ActiveView.destroy_view();
        App.ActiveViewModel.destroy();

        App.ActiveViewModel = new App.Models.Dashboard;
        App.ActiveViewModel.fetch().then(function(){
            App.ActiveView = new App.Views.Dash({model: App.ActiveViewModel });
            App.ActiveView.render();
        });
    },

    users: function(user_id) {
        App.ActiveView.destroy_view();
        App.ActiveViewModel.destroy();

        App.ActiveViewModel = new App.Models.User;
        App.ActiveViewModel.fetch().then(function() {
            App.ActiveView =  new App.Views.UsersView({model: App.ActiveViewModel});
            App.ActiveView.render();
        });
    }
});

Another approach:

Create an AbstractView

Having an AbstractView declared and then extending your other application specific View's from AbstractView has many advantages. You always have a View where you can put all the common functionalities.

App.AbstractView = Backbone.View.extend({
    render : function() {
        App.ActiveView && App.ActiveView.destroy_view();
        // Instead of destroying model this way you can destroy 
        // it in the way mentioned in below destroy_view method.
        // Set current view as ActiveView
        App.ActiveView = this;
        this.renderView && this.renderView.apply(this, arguments);
    },
    // You can declare destroy_view() here
    // so that you don't have to add it in every view.
    destroy_view : function() {
        // do destroying stuff here
         this.model.destroy();
    }
});

Your App.Views.UsersView should extend from AbstractView and have renderView in place of render because AbstractView's render will make a call to renderView . From the Router you can call render the same way App.ActiveView.render();

App.Views.UsersView = AbstractView.extend({
    renderView : function() {
    }
    // rest of the view stuff
});

App.Views.Dash = AbstractView.extend({
    renderView : function() {
    }
    // rest of the view stuff
});

Router code would then change to :

 dashboard: function() {
        App.ActiveViewModel = new App.Models.Dashboard;
        App.ActiveViewModel.fetch().then(function(){
            new App.Views.Dash({model: App.ActiveViewModel }).render();
        });
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM