骨干路由器:等待首先获取数据

Arn*_*old 11 logic routes backbone.js

我认为我不太了解正确使用Backbone路由器背后的想法.这是我得到的:

我有一些数据,我在页面加载时从服务器获取数据,然后将其打包到模型和集合中.这些模型和集合的数量是无限的.我想使用路由器能够从一开始就直接呈现某个集合的视图.

问题是:Backbone路由器提前启动,因为我要求它访问某个视图并触发其render动作,所以它不能这样做,因为那些视图尚未创建.这意味着我实际上必须在获取完成后启动我的路由.

我不知道这是否是一种正确的方法,但我想出的唯一想法是:

  1. 将路由定义和Backbone.history.start();位包装到单独的顶级可访问函数中(即稍后准备手动调用).
  2. 运行该函数作为success我的集合的回调fetch()
  3. 这些集合的数量是未知的,我也无法找到所有这些集合的提取时间,而且我不想多次启动这些路由.所以我利用_.defer()_.once().

这有效,但肯定看起来很奇怪:

路由器:

    window.startRoutes = _.once(function() {

        var AccountPage = Backbone.Router.extend({

          routes: {
            'set/:id': 'renderSet',
          },

          renderSet: function(setId) {

              /** … **/

              // Call the rendering method on the respective CardView
              CardsViews[setId].render();

          }

        });

        var AccountPageRouter = new AccountPage;

        Backbone.history.start();

    });
Run Code Online (Sandbox Code Playgroud)

采集:

window.CardsCollection = Backbone.Collection.extend({

    model: Card,

    initialize: function(params) {

        /** … **/

        // Get the initial data
        this.fetch({success: function() {
            _.defer(startRoutes);
        }});

    },

});
Run Code Online (Sandbox Code Playgroud)

所以我的问题是......我做得对吗?或者有更好的方法(必须)吗?

Eri*_*sel 14

您可以提前定义路由器; 在调用Backbone.History.start()之前,它不会做任何事情.

您可以绑定集合上的"重置"事件以启动历史记录,如下所示:

my_collection.bind("reset", _.once(Backbone.History.start, Backbone.History))
Run Code Online (Sandbox Code Playgroud)

然后路由器将在您的集合完全加载时开始执行操作.我不确定这是否正是您正在寻找的(因为您提到了可变数量的集合).

我有类似的情况,除了我事先知道在开始路由之前我想要加载哪些集合.我在我的路由器上添加了一个startAfter方法,如下所示:

  window.Workspace = new (Backbone.Router.extend({
    . . .
    startAfter: function(collections) {
      // Start history when required collections are loaded
      var start = _.after(collections.length, _.once(function(){
        Backbone.history.start()
      }))
      _.each(collections, function(collection) {
        collection.bind('reset', start, Backbone.history)
      });
    }
  }));
Run Code Online (Sandbox Code Playgroud)

然后在我设置我的收藏品之后

  Workspace.startAfter([collection_a, collection_b, ...])
Run Code Online (Sandbox Code Playgroud)

这可以适用于独立模型,虽然我认为你需要绑定到'重置'事件以外的东西.

我很高兴我阅读了你的示例代码,使用_.once和_.defer指出了我正确的方向.

  • 你对`_.cece()`使用了错误的参数.我会编辑你的答案来解决这个问题.kthxbye :) (2认同)