1

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

  1. 从服务器获取数据
  2. 在通知视图之前向模型添加从零开始的索引
  3. 最后运行让视图触发“渲染”事件

我试图通过在集合中使用成功回调来做到这一点

查看之前

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)

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

4

3 回答 3

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)

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

于 2013-03-15T20:52:50.193 回答
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
于 2013-03-13T02:01:02.297 回答
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);
   }
}
于 2013-03-14T08:36:33.250 回答