在Backbone.js中异步呈现每个集合项

在Backbone.js中异步呈现每个集合项,backbone.js,backbone-views,Backbone.js,Backbone Views,我正在尝试渲染一组项目。通常我会这样做: StuffView = Backbone.View.extend({ ... render: function(){ ... this.$el.html( ... ); return this; } ... }); StuffCollectionView = Backbone.View.extend({ ... render: function(){ this.collection.each(ad

我正在尝试渲染一组项目。通常我会这样做:

StuffView = Backbone.View.extend({
  ...
  render: function(){
    ...
    this.$el.html( ... );
    return this;
  }
  ...
});

StuffCollectionView = Backbone.View.extend({
  ...
  render: function(){
    this.collection.each(addOne, this);
  },
  addOne: function(stuff){
    var view = new StuffView({model: stuff});
    this.$el.append(view.render().el);
  }
  ...
});
StuffView = Backbone.View.extend({
  ...
  render: function(){
    ...
    // Asynchronous rendering
    SlowRenderingFunction(function(renderedResult){
      this.$el.html(renderedResult);
    });
  }
});
然而,这次我构建了一个稍微不同的视图类型。每个StuffView的渲染都需要一些时间,因此我无法同步执行此操作。新StuffView的代码如下所示:

StuffView = Backbone.View.extend({
  ...
  render: function(){
    ...
    this.$el.html( ... );
    return this;
  }
  ...
});

StuffCollectionView = Backbone.View.extend({
  ...
  render: function(){
    this.collection.each(addOne, this);
  },
  addOne: function(stuff){
    var view = new StuffView({model: stuff});
    this.$el.append(view.render().el);
  }
  ...
});
StuffView = Backbone.View.extend({
  ...
  render: function(){
    ...
    // Asynchronous rendering
    SlowRenderingFunction(function(renderedResult){
      this.$el.html(renderedResult);
    });
  }
});
在这种情况下,我不能从render返回这个,并将其结果附加到StuffCollectionView的el。我想到的一个技巧是将回调函数传递给StuffView的渲染,并在渲染完成后让它回调。下面是一个例子:

StuffView = Backbone.View.extend({
  ...
  render: function(callback){
    ...
    // Asynchronous rendering
    SlowRenderingFunction(function(renderedResult){
      this.$el.html(renderedResult);
      callback(this);
    });
  }
});


StuffCollectionView = Backbone.View.extend({
  ...
  initialize: function(){
    _.bindAll(this, "onStuffFinishedRendering");
  },
  render: function(){
    this.collection.each(addOne, this);
  },
  addOne: function(stuff){
    var view = new StuffView({model: stuff});
    view.render(onStuffFinishedRendering);
  },
  onStuffFinishedRendering: function(renderedResult){
    this.$el.append(renderedResult.el);
  }
  ...
});

但由于某种原因它不起作用。此外,这感觉太粗糙,感觉不对劲。是否有一种异步呈现子视图的常规方法

您不能将StuffCollectionView的el传递到SlowRendering函数吗?这有点恶心,但我不明白为什么不起作用


编辑:我应该说,并使SlowRenderingFunction成为StuffView的一个实际属性,以便StuffViewCollection可以调用它而不是调用render。

您可以尝试使用u.defer来防止集合项呈现阻塞UI

有关更多详细信息,请参阅

StuffCollectionView = Backbone.View.extend({
  ...
  render: function(){
    var self = this;
    _(function() {
      self.collection.each(addOne, self);
    }).defer();
  }
  ...
});

在StuffCollectionView的render中传递this.addOne,并在addOne do view.render中传递(this.onstuffinishedrendering)。我想这会管用的。但我同意这不是最好的方式:)