backbone:渲染这个集合

时间:2014-02-24 08:35:11

标签: javascript backbone.js

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并且不会在页面上显示任何内容。

1 个答案:

答案 0 :(得分: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函数,则需要直接在集合中访问models数组,如@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;
}

编辑2

以下是您的提取呼叫可能无法正常工作的一些原因。首先检查您使用的是Web服务器,因为使用文件系统可能会出于安全原因阻止ajax请求。我知道除非您更改某个设置,否则会在Chrome中屏蔽此功能。不确定Firefox。

第二个原因是fetch call是异步的。这意味着,当您运行initialize

时,很可能无法加载您的数据

这意味着您需要进行以下调整。首先,您需要为集合的add事件添加一个侦听器,以便无论何时添加项目,都会通知您的视图。

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);
    });