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

Posted

技术标签:

【中文标题】骨干路由器:等待首先获取数据【英文标题】:Backbone Routers: wait for data to be fetched first 【发布时间】:2011-12-10 23:22:52 【问题描述】:

我认为我不太明白正确使用 Backbone 路由器背后的想法。这是我得到的:

我有一些数据在页面加载时从服务器获取,然后将其打包到模型和集合中。这些模型和系列的数量是不确定的。我希望使用路由器能够从一开始就直接渲染某个集合的视图。

问题是:骨干路由器启动得很早,因为我要求它访问某个视图并触发其render 操作,它不能这样做,因为这些视图尚未创建。这意味着我实际上必须在获取完成后启动我的路线。

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

    将路由定义和Backbone.history.start(); 位包装到一个单独的***可访问函数中(即准备稍后手动调用它)。 将该函数作为我收藏的fetch()success 回调运行 这些集合的数量是未知的,我也没有办法知道它们什么时候都被提取了,我不想多次启动路由。所以我使用_.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();

    );

收藏:

window.CardsCollection = Backbone.Collection.extend(

    model: Card,

    initialize: function(params) 

        /** … **/

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

    ,

);

所以我的问题是……我做得对吗?还是有更好的方法来做到这一点(必须)?

【问题讨论】:

为什么要立即进行ajax调用?为什么不简单地使用初始数据加载所需的 json 渲染页面并将数据传递到主干启动? 【参考方案1】:

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

您可以在您的收藏上绑定“重置”事件以启动历史记录,如下所示:

my_collection.bind("reset", _.once(Backbone.History.start, Backbone.History))

然后,当您的集合完全加载时,路由器将开始处理。我不确定这是否正是您要寻找的(因为您提到有可变数量的集合)。

我也有类似的情况,只是在开始路由之前我提前知道要加载哪些集合。我在路由器中添加了一个 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)
      );
    
  ));

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

  Workspace.startAfter([collection_a, collection_b, ...])

这也可以适用于独立模型,尽管我认为您需要绑定到“重置”事件以外的其他东西。

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

【讨论】:

不是my_collection.bind("reset", _.once(Backbone.history.start))吗? 您对_.once() 使用了错误的参数。我将编辑您的答案以解决此问题。 kthxbye :) _.once() 示例对我不起作用。我不得不使用:app.users.on("reset", _.once(function () Backbone.history.start(); ));【参考方案2】:

我只是在我的.render() 方法中检查是否填写了所有必填字段,然后再使用它。如果尚未填充 - 我正在渲染一个“Loading...”小部件。

我所有的视图都订阅了模型更改,this.model.bind('change', this.render, this);,所以在模型加载后,render() 将被再次调用。

【讨论】:

以上是关于骨干路由器:等待首先获取数据的主要内容,如果未能解决你的问题,请参考以下文章

OSPF多区域配置;骨干区域与非骨干区域;ABR边界路由器;LSA和SPF算法

非骨干区域通过虚链路穿越非骨干区域连接骨干区域实现互联互通

OSPF动态路由协议之——虚链路

华为路由器OSPF特殊区域配置

OSPF多个区域连通

大规模网络路由配置及分析