Backbone.js在重置事件发生之前修改新获取的集合

时间:2013-03-13 01:53:23

标签: backbone.js backbone-views backbone-events

我正在尝试执行以下操作:

  1. 从服务器获取数据
  2. 在通知视图之前向模型添加从零开始的索引
  3. 最后运行会为视图启动'render'事件
  4. 我试图通过在集合中使用成功回调来做到这一点

    查看之前

    initialize: () ->
      @collection.on 'reset', @render, this
    
    render: () -> ...render code...
    

    收藏前

    search: () ->
      @fetch { 
        success: @fetch_success
      }  
    
    fetch_success: () ->
      for i in [0...collection.models.length]
        collection.models[i].set('go_index', i)
    

    以这种方式执行操作会导致视图在成功回调更新集合之前触发其渲染事件。我想出的解决方案是让视图监听fetched事件,然后在成功修改集合后触发集合:

    查看

    initialize: () ->
      @collection.on 'fetched', @render, this
    
    render: () -> ...render code...
    

    收集后

    initialize: () ->
      @on 'reset', @add_index_and_notify, this
    
    add_index_and_notify: () ->
      for i in [0...@models.length]
        @models[i].set('go_index', i)
      @trigger('fetched')
    

    这很好用,我只是想知道这是否是实现这一目标的最优雅方式,或者是否存在我缺少的内置方式。

    更新3/15

    我想出了一个更清晰的解决方案,它不需要视图来执行任何脏工作,我也不必创建自定义事件。诀窍是收听sync事件(在 reset之后触发

    查看最终

    initialize: () ->
      @collection.on 'sync', @render, this
    
    render: () -> ...render code...
    

    收藏决赛

    initialize: () ->
      @on 'reset', @add_index, this
    
    add_index: () ->
      for i in [0...@models.length]
        @models[i].set('go_index', i)
    

    希望这种模式可以帮助将来搜索的人。

3 个答案:

答案 0 :(得分:3)

我已经在原始问题中发布了解决方案,但我认为我正式发布了一个答案:

清洁解决方案不要求视图执行任何脏工作,也不需要自定义事件。诀窍是收听sync事件(在 reset之后触发

查看最终

initialize: () ->
  @collection.on 'sync', @render, this

render: () -> ...render code...

收藏决赛

initialize: () ->
  @on 'reset', @add_index, this

add_index: () ->
  for i in [0...@models.length]
    @models[i].set('go_index', i)

希望这种模式可以帮助将来搜索的人。

答案 1 :(得分:1)

您的视图应该将模型及其索引与集合分开,因为索引实际上不是模型记录本身的一部分。尝试让您的视图使用collection.each循环遍历模型,因为回调函数会将model, index, collection作为参数。请记住,视图不仅可以将单个模型传递给其模板。

class CollectionView1 extends Backbone.View
  render: =>
    $el = @$el
    $el.empty()
    @collection.each (model, index) ->
      modelView = new ModelView1 {model, index}
      $el.append modelView.render().el
    return this

答案 2 :(得分:0)

为什么不听集合的添加事件 ..

initialize: function() {
  this.listenTo(this.collection, 'reset', this.render);
  this.listenTo(this.collection , 'add' , this.add_index_and_notify);
  this.index = 0;
},

add_index_and_notify: function(model){
    model.set({go_index : this.index++}, {silent : true});
    // Render the model here
},

render: function(){
   this.$el.empty().append(Your template);
   this.index= 0;
   _.each(this.collection.models, function(model){
         this.add_index_and_notify(model);
   }
}