如何在BACKBONEJS + requireJS中避免这个长路由器文件?

时间:2012-06-04 01:00:23

标签: jquery backbone.js requirejs router

// Filename: router.js

define(['jquery','underscore','backbone',
'collections/series','views/series/list','text!templates/series/list.html',
'models/series',
    'views/series/details','text!templates/series/details.html',
    'views/series/preview','text!templates/series/preview.html'
], function($, _, Backbone,
        SeriesCollection, SeriesListView, SeriesListTemplate,
        SeriesModel,
        SeriesDetailsView, SeriesDetailsTemplate,
        SeriesPreviewView, SeriesPreviewTemplate
){

_.templateSettings = { interpolate : /\{\{(.+?)\}\}/g };

...

更新:

所有这一切的原因是在我的路由器的功能中我正在这样做:

 seriesList: function(){
  // We have no matching route, lets display the home page

    var seriesCollection = new SeriesCollection();
    seriesCollection.fetch({success:function(){

        var seriesListView = new SeriesListView({collection:seriesCollection, el:'#page'});
        seriesListView.template = _.template(SeriesListTemplate);
        seriesListView.render();
    }});

}

含义 - 我在数据返回时连接模板和视图。 它有效 - 但这是一种很好的做法吗?

5 个答案:

答案 0 :(得分:1)

在我看来,你的路由器是一种神对象。它知道的太多了。我认为重构应用程序是有意义的,以便更清楚地分离关注点。然后你的路由器将不会像上面那样,并且不会有这么多的依赖项。 例如,您可以让视图负责其自己的模板(顺便说一下,以及渲染自身):

// router.js
seriesList: function(){
    var seriesCollection = new SeriesCollection();
    var seriesListView = new SeriesListView({collection:seriesCollection, el:'#page'});
    seriesCollection.fetch();
}

// view/series/list.js
define(['jquery',
       'underscore',
       'backbone',
       'text!templates/series/list.html'], function($, _, Backbone, SeriesListTemplate){

    var SeriesListView = Backbone.View.extend({
        template: _.template(SeriesListTemplate),

        initialize: function (options) {
            this.collection.on('reset', this.render, this);
        }
        ...
    });
    return SeriesListView;
}

然后相应的模板依赖关系将远离router.js。

答案 1 :(得分:1)

您是否考虑过将单条路线划分为不同的路线?

正如Backbone文档所说,确保在DOM-ready(对于IE)上运行Backbone.history.start并且在启动所有路由器之后。

$(function(){
  new WorkspaceRouter;
  new HelpPaneRouter;
  Backbone.history.start({pushState: true});
});

我没有意识到的是Backbone.history是“主”路由器,因此您可以在子路由器上设置.bind个事件,以便仅影响这些路由或.bind在Backbone上。历史影响他们所有。显然,这意味着您可以在master上设置辅助方法,以便在所有子路由器上重用。

答案 2 :(得分:0)

问题是,至少如果我理解的话,你试图一次性加载所有内容,以便它可以用于某些设置吗?

例如,为什么要在视图之外的系列详细信息模板中加载?

尝试这个答案我今天给了一个人,我举了一个AMD如何在这里工作的例子: Backbone Design 或者要点: https://gist.github.com/2863979

正如您所看到的,我没有在一个巨大的router.js文件中加载所有内容。

一个很好的资源: http://addyosmani.github.com/backbone-fundamentals/#modularjs

P.S。 我没有遇到为backbone和require.js的router.js文件的概念。你在哪里得到这个想法?

答案 3 :(得分:0)

您可以将依赖项移动到路由处理程序:

define(['backbone'], function (Backbone) {

    var Router = Backbone.Router.extend({

        routes: {
            "Series(/)": "seriesList"
        },

        seriesList: function() {
            require(['collections/series', 'views/series/list'], function(SeriesCollection, SeriesListView) {
                var seriesCollection = new SeriesCollection();
                var seriesListView = new SeriesListView({collection:seriesCollection, el:'#page'});
                seriesCollection.fetch();
            });
        } 
    });
});

这使得define()调用更易于管理,并推迟加载,直到实际使用该路由。

答案 4 :(得分:0)

这是另一种方式:

  1. 实例化不知道任何路由的路由器(全局或应用程序成员)
  2. 在每个视图的initialize()方法中,定义该视图处理的路由
  3. router.route('tasks','tasks',function(){             ...         })

    1. 在调用Backbone.history.start()
    2. 之前,在主App视图中实例化所有顶级视图
    3. (可选)在启动应用时导航到默认视图路径
    4. http://mariusa.github.io/writings/handling-backbone-routes.html

      的更多解释和示例代码