2014-02-24 103 views
2
var Text = Backbone.Model.extend({}); 

Texts = Backbone.Collection.extend({ 
    model: Text, 
    url: '/data.json', 
}); 

var TextsView = Backbone.View.extend({ 
    initialize: function() { 
     _.bindAll(this); 
     this.render(); 
    }, 
    el: "#Texts", 
    template: _.template($('#TextTemplate').html()), 
    render: function(e){ 
     _.each(this.model.models, function(Text){ 
      var TextTemplate = this.template(Text.toJSON()); 
      $(this.el).append(TextTemplate); 
     }, this); 
     return this; 
    } 
}) 

var Texts = new Texts(); 
Texts.fetch(); 
var TextView = new TextsView({collection: Texts}); 

这给我Uncaught TypeError: Cannot read property 'models' of undefined并且不在页面上显示任何内容。backbone:渲染此集合

回答

2

this.model.models应该this.collection

在渲染处理方法在你看来,你应该使用的this.collection.each代替_.each功能。

render: function(e){ 
    this.collection.each(function(Text){ 
     var TextTemplate = this.template(Text.toJSON()); 
     $(this.el).append(TextTemplate); 
    }, this); 
    return this; 
} 

如果你想使用_.each功能,那么您就需要直接访问模型数组您的收藏作为@dfsq指出。这可以通过使用this.collection.models来完成。

render: function(e){ 
    _.each(this.collection.models, function(Text){ 
     var TextTemplate = this.template(Text.toJSON()); 
     $(this.el).append(TextTemplate); 
    }, this); 
    return this; 
} 

EDIT 2

这里有一些原因,你的抓取通话可能无法正常工作。首先检查您是否使用Web服务器,因为使用文件系统出于安全原因可能会阻止Ajax请求。我知道这在Chrome中被阻止,除非您更改某个设置。不确定关于Firefox。

第二个原因是提取call是异步的。这意味着很可能您的数据在运行时不会被加载initialize

这意味着您需要进行以下调整。首先,您需要将监听器添加到收藏夹的添加事件中,以便随时添加项目,您的视图将被通知。

initialize: function() { 
    _.bindAll(this); 
    this.render(); 
    // Listen to the `add` event in your collection 
    this.listenTo(this.collection,"add", this.renderText); 
}, 

接下来,我们需要添加一个功能,您认为将呈现单个项目

renderText: function(Text) { 
    var TextTemplate = this.template(Text.toJSON()); 
    this.$el.append(TextTemplate);   
} 

还为您解答的this在每个循环用户的其他问题。每个函数中的最后一个参数是您希望在执行的回调函数内使用的范围。因此,如果您使用this作为第二个参数,则它允许您使用this访问您的查看。

this.collection.each(function(Text){ 
     var TextTemplate = this.template(Text.toJSON()); 
     $(this.el).append(TextTemplate); 
    }, this); 

如果不加this,那么你需要做:

var view = this; 
    this.collection.each(function(Text){ 
     var TextTemplate = view.template(Text.toJSON()); 
     $(view.el).append(TextTemplate); 
    }); 
+1

在我看来,它应该是'this.collection.models'。 – dfsq

+0

他使用Backbone,所以'this.collection'指的是他创建的'Texts'集合。这应该使循环工作,但我想你可以直接使用'this.collection.models'来访问模型。不知道。有趣。 – Gohn67

+0

其实你是对的@dfsq。如果你使用每个方法的下划线,那么你确实需要使用'this.collection.models'。最近一定改变了。无论如何改变它使用集合上的每个方法。 – Gohn67