2012-11-27 84 views
8

我試圖做基本的渲染()後取()在集合(骨幹0.9.2):調試Backbone.js的:渲染採集後取()

var ProjectListView = Backbone.View.extend({ 
     el: $('#container'), 
     initialize: function() { 
      this.collection = new ProjectsCollection(); 
      this.collection.bind("change", _.bind(this.render, this)); 
      this.collection.fetch({ success: function() { console.log("collection fetched"); } }); 
      ... 
      }, 
     render: function() { 
      console.log("rendered"); 
      ... 

創建新的視圖實例打印出:

collection fetched

所以render()永遠不會在fetch()之後被調用。我在這裏做錯了什麼?目前沒有例外。

任何提示如何調試這些在骨幹的東西?

Ps。 考慮到SO上的問題數量,似乎這個功能記錄很差。

回答

28

fine manual

collection.fetch([options])

取來自服務器的這個集合的默認模型集合,當它們到達時重置集合。 [...]當模型數據從服務器返回時,集合將重置。

reset是做什麼用的? reset做到這一點:

重置collection.reset(models, [options])

[...]使用重置與型號的新列表替換集合(或屬性散列),在觸發一個事件"reset"結束。

所以fetch呼籲reset更新收集的模型和reset觸發"reset"事件,而不是一個"change"事件。沒有一個模型已經改變,並且一個集合的事件來自其模型。

你應該render勢必"reset"

initialize: function() { 
    this.collection = new ProjectsCollection(); 
    this.collection.bind("reset", _.bind(this.render, this)); 
    this.collection.fetch(...); 
} 

如果你想監聽對包含模型"change"事件,那麼你可以在"change"處理程序綁定到集合since

你可以綁定"change"事件,當集合中的任何模型已被修改時將被通知,
[...]
爲方便起見,集合中的模型上觸發的任何事件也將直接在集合上觸發。

集合本身也會隨着集合本身的變化而生成"add""remove"事件。在fetch


新版本骨幹的不再重置類別:

當從服務器模型數據的回報,它採用設置到(智能)合併所取得的模型,除非你通過{reset: true},在這種情況下,收集將(有效)重置

而且set

[...]執行與模型傳遞的列表中集合的 「智能」 的更新。如果列表中的某個模型尚未處於集合中,則會添加該模型;如果模型已經在集合中,它的屬性將被合併;並且如果集合包含列表中不存在的任何模型,則它們將被刪除。所有適當的"add""remove""change"事件被解僱,因爲這發生

因此,與骨幹網的新版本,你會希望列出的"add""remove""change"事件(集合基於視圖應該無論如何要聽);您還可以在初始fetch上使用{reset: true},並聽取"reset"。我建議以下辦法收集爲本次:

  1. "add"和處理與簡單地增加一個項目視圖中的回調事件,不亂扔一切的和重新渲染。
  2. 收聽"remvoe"並使用僅刪除新移除的模型的回調來處理該事件。
  3. 收聽"change"並使用回調代替(或更新)適當的項目。
  4. 收聽"reset"並將其綁定到render。然後將{reset: true}傳遞給該集合的初始fetch呼叫。

這將陷阱的重要事件和收集視圖將做最少量的工作來處理每個。當然,這種策略並不適用於所有情況,但我認爲這是一個很好的起點。

+0

謝謝您的詳細解答,希望這對其他人有用。 PS。除官方文檔外,還有其他資源可以推薦嗎? – Fdr

+0

@Fdr:我閱讀了文檔和源代碼以供參考。經過15年以上,所有的框架看起來都差不多。 –

+0

我想是的。骨幹中的這些事件有點跳閘:爲集合引發了「重置」,但在執行model.fetch()(導致發出「更改」)時沒有相似性。弱api設計? – Fdr

3

好了,直到有人可以解釋爲什麼綁定沒有工作,我用以下解決方法:

initialize: function() { 
      var self = this; 
      this.collection = new ProjectsCollection(); 
      this.collection.fetch({ success: function() { self.render(); } });