2012-02-18 34 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