【问题标题】:How to remove Backbone views with require.js?如何使用 require.js 删除 Backbone 视图?
【发布时间】:2017-12-06 22:03:07
【问题描述】:

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

在使用 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 );

}
});

我会将“当前”视图存储在全局变量中,并在每次更改路线并且生活良好时终止现有视图。

但是,我如何使用 require.js 来实现这一点?

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

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 ;

});

【问题讨论】:

    标签: javascript backbone.js requirejs iife


    【解决方案1】:

    即使在使用 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);
            }
        });
    })();
    

    【讨论】:

    • 谢谢!不知道为什么我从来没想过。我使用异步要求的唯一原因是因为我的视图依赖于路由器,并且我试图避免循环依赖。除非,有更好的方法来处理这种情况?
    • @master00 你的视图不应该依赖于路由器,但你是对的,这样的异步需求是避免循环依赖的唯一解决方案(没有重构)。跨度>
    • 好的,知道了。那么,从视图中调用 router.navigate() 从来没有实际的情况吗?
    • 太好了,谢谢。我仍在尝试围绕所有概念进行思考。现在几乎认输了很多次,但你帮助我理解了一些让我头疼的事情。当我弄清楚所有事情时,我确信已经有一些新技术我必须重新学习;)
    • 是的,我开始意识到这一点。我正在研究 Vue,但我已经在 Backbone 中浪费了很多时间。在这一点上,只要我有任何可扩展的架构来完成我的项目,我很乐意接受。
    猜你喜欢
    • 2015-02-07
    • 2012-04-19
    • 2012-11-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多