如何使用 require.js 删除 Backbone 视图?

How to remove Backbone views with require.js?

我有一个使用 require.js 的 backbone 应用程序。

使用 require 之前,我的 Backbone 路由器看起来像这样。

APP.views = {};

APP.Router = Backbone.Router.extend({

routes: {

    '(/)' : 'index',
    'about(/)' : 'about'

},

initialize : function(){
    Backbone.history.start({ pushState: true });
},

index: function() {
    this.showView( new APP.Views.IndexView() );
},

about: function() {
    this.showView( new APP.Views.AboutView() );
},

showView : function( view ) {

        if ( APP.views.current ) {
            APP.views.current.remove();
        }
        APP.views.current = view;
        $( '#page' ).html( view.render().$el );

}
});

我会将 'current' 视图存储在全局变量中,并在每次更改路线时终止现有视图并且生活很好。

但是,如何使用 require.js 实现此目的?

我的 requirejs 路由器目前如下所示,但我不确定如何删除现有视图。虽然,我没有注意到任何典型的 "zombie view" 症状,但我觉得我应该删除现有视图。

define( function( require ){

    // DEPS
    var $           = require('jquery'),
        _           = require('underscore'),
        Backbone    = require('backbone');

    // ROUTER
    var Router = Backbone.Router.extend({

        routes: {

            '(/)' : 'index',
            'about(/)' : 'about'

        },
        initialize : function(){

            Backbone.history.start({ pushState: true });

        },
        index: function(){

            this.showPage('index');

        },
        about: function() {

            this.showPage('about');

        },
        showPage : function( pageName ) {

            var view = 'views/pages/' + pageName;

            require( [ view ] , function( Page ) {

                var page = new Page();

                $('#page').html( page.render().el );

            });

        }

    });

    return Router ;

});

甚至在使用 require.js 之前,也不需要全局变量。

只需将当前视图放入路由器 属性。

initialize : function() {
    this.$page = $('#page');
    Backbone.history.start({ pushState: true });
},
showView : function(view) {
    if (this.current) this.current.remove();
    this.$page.html((this.current = view).render().el);
}

然后,同样的事情适用于你的异步需求案例:

showPage : function(pageName) {
    if (this.current) this.current.remove();

    var view = 'views/pages/' + pageName,
        self = this;
    require([view], function(Page) {
        self.$page.html((self.current = new Page()).render().el);
    });
}

但即使那样,我也不觉得要求每个视图都具有异步 require 是值得的。您只是因为大量额外请求而减慢了您的应用程序。

只需定义每个模块的依赖项。

define([
    'jquery',
    'backbone',
    'views/index', 
    'views/about'
], function($, Backbone, IndexView, AboutView){
    // ...
});

在开发过程中,每次刷新时您都会看到很多请求,但是当准备好投入生产时,使用 require optimizer.

构建所有 js 文件的缩小包

另请注意,您可以将模块作用域设为全局,这只是在模块作用域的根部声明的局部变量(IIFE 或使用 require.js)。

(function() {
    var currentView;

    var Router = Backbone.Router.extend({
        // ...snip...
        showView: function(view) {
            if (currentView) currentView.remove();
            this.$page.html((currentView = view).render().el);
        }
    });
})();