2014-03-26 42 views
3

我知道有關於這個問題的幾個問題,但答案並不是非常明確,我可以實現。這就是爲什麼我再次問這個問題,所以我可以有一個清晰而簡單的答案。Backbone:集合在View中不呈現,即使它被提取

我一直在Backbone的Collection遇到問題,特別是使用JSON數據填充它。

我似乎無法得到集合呈現在視圖中,即使在螢火蟲我可以看到,它是從服務器獲取,但屏幕仍然是空的。 另外,當我做一個console.log('callers: ', this.callerList)時,它返回一個包含models=[0]的對象。但是當我展開該對象時,models充滿了來自JSON文件的數據。 Backbone發生了什麼,這是令人困惑的結果?

有人可以請向我解釋如何做到這一點?我一直在和這個爭鬥多年,我無法理解它。

非常感謝

JS:

(function($, window) { 

    // model 
    var CallerModel = Backbone.Model.extend({}); 

    // collection 
    var CallersList = Backbone.Collection.extend({ 
     model: CallerModel, 
     url: 'js/json/callers.json' 
    }); 

    // view 
    var CallerView = Backbone.View.extend({ 
     el: '.caller-app', 

     template: _.template($('#callers-template').html()), 

     initialize: function() { 
      this.callerList = new CallersList(); 
      this.callerList.fetch(); 
      this.callerList.bind('reset', this.render); 

      console.log('caller: ', this.callerList); 
     }, 

     render: function(e) { 

        console.log('RENDER'); 

      _.each(this.collection.models, function(caller) { 
       this.$el.append(this.template(caller.toJSON())); 
          console.log('callerList: ', caller); 
      }, this); 

      return this; 
     } 
    }); 

    // start 
    var callerView = new CallerView(); 

}(jQuery, window)); 

HTML:

<!-- wrapper --> 
<div class="wrapper"> 
    <h1>Missed Calls App</h1> 

    <div class="caller-app"></div> 

</div> 
<!-- wrapper --> 


<!-- templates --> 
<script type="text/template" id="callers-template"> 
    <div class="caller"> 
     <h2><%= title %> <%= name %> called</h2> 
     <h3>From <%= agency %></h3> 
     <p>When: <%= when %></p> 
     <p>Contact: <%= tel %></p> 
     <p>Says:"<%= message %>"</p> 
    </div> 
</script> 
<!-- templates --> 

JSON:

[ 
    { 
     "id": 1, 
     "title": "Mrs", 
     "name": "Mui", 
     "agency": "Ryuzanpaku Dojo", 
     "when": "evening", 
     "tel": "0207 123 45 67", 
     "message": "Check your availability" 
    }, 
    { 
     "id": 2, 
     "title": "Mrs", 
     "name": "Shigure", 
     "agency": "Ryuzanpaku Dojo", 
     "when": "evening", 
     "tel": "0207 123 45 67", 
     "message": "Check your availability" 
    } 
] 
+1

我沒有看到任何明顯的問題。我建議你在這個點上放一個斷點。$ el.append(this.template(caller.toJSON()));'。檢查調用者是否正確,並且該caller.toJSON()返回您認爲應該的內容。驗證this.template是否正確,$ el是否正確等。 – Neil

+0

Thanks @Neil for respond。我在render函數中添加了一些'console.log'來查看'caller'裏面的內容,但是好像'render'甚至沒有被應用。 – Shaoz

+0

您試圖遍歷集合,但您尚未實際分配它,此外您正在使用this.model而不是this.collection。 – Jack

回答

2

您還沒有actaully分配收集到您CallerVie w^,除了當你迭代雖然你應該初始化你什麼時候來電記錄 初始化使用this.collection.models代替this.model.models

例如集合:函數(){

initialize: function() { 
    this.collection = new CallersList(); 
    this.collection.fetch(); 
    this.collection.bind('reset', this.render); 
    } 

和渲染

render: function(e) { 

      _.each(this.collection.models, function(caller) { 
       this.$el.append(this.template(caller.toJSON())); 

      }, this); 

      return this; 
     } 

這是鏈接到jsbin

一些其他要點

一般而言,您希望儘可能地分離您的代碼。爲此,最好在你的視圖之外聲明並初始化你的集合,然後傳遞它。這也有利於讓你的代碼更加可重用,例如說你想呈現第二個調用列表(讓我們來說最近調用),現在可以創建視圖的第二個實例,傳入一個集合和元素。

例如

var missedCalls = new CallersList(); 
var callerView = new CallerView({collection : missedCalls, el: '#missedCalls' }); 
missedCalls.fetch(); 


var recentCalls = new CallerList(); //you probably want to use a different url 
var recentCallersView = new CallerView({collection : recentCalls, el:'#recentCalls'}); 
recentCalls.fetch(); 

還有一點值得一提的是,目前正進行渲染的所有項目您的收藏在每次提取,包括任何已經被渲染。您可能希望在呈現之前清空el或者聽取add事件,並在添加每個項目時單獨呈現每個項目。另外值得指出的是fetch是不是真的意味着要用來加載頁面加載數據,從documentation

注意獲取不應該被用來填充頁面上的集合 負載 - 所需的所有車型在加載時應該已經引導 進去。取指適用於不需要立即需要的 接口的延遲加載模型:例如,文檔 帶有可能被打開和關閉的註釋集合。

+0

謝謝@Jack。我仍然困惑。通過將集合分配給'View',你的意思是什麼?這也不能解釋爲什麼JSON數據不顯示在屏幕上。我知道手動插入數據,但是這次我希望顯示來自服務器的數據,因爲這是現實世界中使用的數據。現在我在'initiliaze'中添加了'this.render()'和JSON中的數據,但它仍然在工作...... :( – Shaoz

+0

我手動分配數據的原因只是因爲它更容易在jsbin中設置,當你獲取數據時它應該是一樣的,至於把集合分配給視圖,backbone [view](http://backbonejs.org/#View-constructor)有一個* model *屬性和一個* collection *屬性(這兩個都不是必需的,但是如果你使用你的視圖作爲模型,那麼你會使用'model'屬性和一個集合''collection'屬性。 – Jack

+0

好吧,我試過了你的jsbin例子,即手動數據,像這樣分配給View:'var callerView = new CallerView({collection:new CallersList})''但是隻要我將手動數據更改爲服務器數據,就不會顯示任何內容。在涉及到來自JSON的數據時,我在代碼中沒有做正確的事情?在應用數據f之前,我必須做些事情rom JSON,無論是服務器還是瀏覽器配置,在Backbone中缺少一段代碼等。這就是我想知道的,如何正確執行。 – Shaoz