2012-11-05 67 views
1

我正在嘗試呈現項目的集合。通常我會做的是這樣的:在Backbone.js中異步呈現每個集合項目

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的渲染需要一些時間,所以我不能同步做到這一點。新StuffView的代碼看起來是這樣的:

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

在這種情況下,我不能只從返回渲染這個及其結果追加到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); 
    } 
    ... 
}); 

但它不工作的原因。而且,這感覺太冒險了,感覺不對。有沒有一種傳統的方法異步渲染子視圖?

+0

將this.addOne傳遞給StuffCollectionView,並在addOne中執行view.render(this.onStuffFinishedRendering)。我認爲這會起作用。但我同意這不是最好的方式:) – deven98602

回答

0

難道你不能通過StuffCollectionView的el SlowRenderingFunction嗎?這有點討厭,但我不明白爲什麼它不起作用。

編輯:我應該說,並使SlowRenderingFunction StuffView的實際屬性,以便StuffViewCollection可以調用它,而不是調用渲染。

0

您可以嘗試使用_.defer來防止集合項呈現阻塞UI。

有關更多詳細信息,請參閱http://underscorejs.org/#defer

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