2012-02-18 32 views
0

我相信我的問題與範圍有關,因爲我是一個js新手。我有一個很小的backbone.js例子,我試圖做的是打印出從服務器獲取的項目列表。使用Backbone.js的範圍錯誤?

$(function(){ 
    // = Models = 
    // Video 
    window.Video = Backbone.Model.extend({ 
     defaults: function() { 
      return { 
       title: 'No title', 
       description: 'No description' 
      }; 
     }, 
     urlRoot: 'api/v1/video/' 
    }); 

    // VideoList Collection 
    // To be extended for Asset Manager and Search later... 
    window.VideoList = Backbone.Collection.extend({ 
     model: Video, 
     url: 'api/v1/video/' 
    }); 

    // = Views = 
    window.VideoListView = Backbone.View.extend({ 
     tagName: 'ul', 

     render: function(eventName) { 
      $(this.el).html(""); 
      _.each(this.model.models, function(video) { 
       $(this.el).append(new VideoListRowView({model:video}).render().el); 
       }, this); 
      return this; 
     } 
    }); 

    // VideoRow 
    window.VideoListRowView = Backbone.View.extend({ 
     tagName: "li", 

     template: _.template("id: <%= id %>; title: <%= title %>"), 

     className: "asset-video-row", 

     render: function() { 
      $(this.el).html(this.template(this.model.toJSON())); 
      return this; 
     } 
    }); 

    // Router 
    var AppRouter = Backbone.Router.extend({ 

     routes:{ 
      "":"assetManager" 
     }, 

     assetManager:function() { 
      this.assetList = new VideoList(); 
      this.assetListView = new VideoListView({model:this.assetList}); 
      this.assetList.fetch(); 
      $('#content').html(this.assetListView.render().el); 
     } 
    }); 

    var app = new AppRouter(); 
    Backbone.history.start(); 

    // The following works fine: 
    window.mylist = new VideoList(); 
    window.mylistview = new VideoListView({model:window.mylist}); 
}); 

如果我從控制檯訪問mylist.fetch(); mylist.toJSON(),mylist填充正常。我可以看到this.assetList.fetch()準確地從後端獲取數據,但它似乎並沒有將對象添加到this.assetList

回答

1

fetch method對骨幹的集合是異步的:

取模型的默認設置爲這個集合從服務器,當他們到達重新集合。 [...]代表Backbone.sync在封面下,用於定製持久性策略。

而且Backbone.sync說:

Backbone.sync是函數調用骨幹每次嘗試讀取或模型保存到服務器的時間。默認情況下,它使用(jQuery/Zepto).ajax來創建RESTful JSON請求。

所以fetch涉及的(異步)AJAX調用,這意味着,你要使用集合fetch已經從服務器中檢索數據之前。需要注意的是獲取支持successerror回調,所以你可以這樣做,而不是:

var self = this; 
this.assetList.fetch({ 
    success: function(collection, response) { 
     $('#content').html(self.assetListView.render().el); 
    } 
}); 

或者你可以綁定回調到集合的reset活動爲fetch將重置集合。然後在集合的reset事件被觸發時呈現您的assetListView

此外,您assetList是一個集合,所以你應該做的:

this.assetListView = new VideoListView({collection: this.assetList}); 

和:

window.VideoListView = Backbone.View.extend({ 
    tagName: 'ul', 

    render: function(eventName) { 
     $(this.el).html(""); 
     _.each(this.collection.models, function(video) { 
      // ... 
+0

所以你爲如何組織結合的情況下,等好的建議,但如果你解釋了我的問題是什麼,我怕我錯過了。 *** 沒關係,它點擊。它是異步的,所以下面的渲染事件不會等待fetch()完成。謝謝!我會測試它,並回來標記正確的,如果它運作。 – akoumjian 2012-02-18 07:46:51

+0

現貨。從這裏開始,我將使用事件綁定。 – akoumjian 2012-02-18 07:50:41

+0

@akoumjian:對,你問題的根源在於你正在嘗試在'fetch'從服務器獲取它之前使用集合。我已經澄清,爲了後代。儘可能地通過事件系統儘可能地爲您節省很多麻煩。 – 2012-02-18 07:59:55