11

我有一组希望在表格视图中呈现的模型。每个模型应由表中的一行表示,并且应使用模板生成该行。我应该能够将事件处理程序附加到该行(例如单击),以便在事件警报时发出有关与该行关联的模型的一些特定信息。

我见过与此类似的事情的一种常见方法是将每一行分成它自己的视图,并有一个父视图(在这种情况下说是表)使用行视图生成要包含在你的代码中的 html . 但是我无法弄清楚这如何与模板一起使用。

在这种情况下,我不能将事件专门附加到 RowView,因为它没有引用 dom 元素(this.el对于主干),它只是返回一个字符串。我怎样才能实现我想要的,同时使用模板来最大容量?

问题不是专门针对事件、模板化或使用嵌套视图,而是更多关于使用 Backbone 实现这种输出的正确方法。

示例代码(也在小提琴中):

/** View representing a table */
var TableView = Backbone.View.extend({
    tagName: 'table',
    render: function() {
        var rows = _.map(this.collection.models, function(p) {
            return new RowView({model: p}).render();                        
        });
        $('body').html(this.$el.html(rows.join('')));
    }
});

/** View representing a row of that table */
var RowView = Backbone.View.extend({
    render: function() {
        // imagine this is going through a template, but for now
        // lets just return straight html.
        return '<tr>' + 
                '<td>' + this.model.get('name') + '</td>' + 
                '<td>' + this.model.get('age') + '</td>' +
               '</tr>';
    }
});

var data = [
    {'name': 'Oli', 'age': 25},
    {'name': 'Sarah', 'age': 20}];

/** Collection of models to draw */
var peopleCollection = new Backbone.Collection(data);
var tableView = new TableView({collection: peopleCollection});
tableView.render();

谢谢!

4

1 回答 1

11

处理视图层次结构的一种方法是让每个视图呈现其子视图并将它们附加到其el. 然后每个视图根据其模型/集合处理事件。

要将 HTML 作为视图注入el并控制容器元素,可以使用setElement方法

设置元素 view.setElement(element)

如果您想将 Backbone 视图应用到不同的 DOM 元素,请使用 setElement,它还将创建缓存的 $el 引用并将视图的委托事件从旧元素移动到新元素。

您的示例可以重写为

var rowTemplate=_.template("<tr>"+
     "<td class='name'><%= name %></td>"+
     "<td class='age'><%= age %></td>"+
     "</tr>");

/** View representing a table */
var TableView = Backbone.View.extend({
    tagName: 'table',

    initialize : function() {
        _.bindAll(this,'render','renderOne');
    },
    render: function() {
        this.collection.each(this.renderOne);
        return this;
    },
    renderOne : function(model) {
        var row=new RowView({model:model});
        this.$el.append(row.render().$el);
        return this;
    }
});

/** View representing a row of that table */
var RowView = Backbone.View.extend({  
    events: {
        "click .age": function() {console.log(this.model.get("name"));}
    },

    render: function() {
        var html=rowTemplate(this.model.toJSON());
        this.setElement( $(html) );
        return this;
    }
});

var data = [
    {'name': 'Oli', 'age': 25},
    {'name': 'Sarah', 'age': 20}];

/** Collection of models to draw */
var peopleCollection = new Backbone.Collection(data);
var tableView = new TableView({collection: peopleCollection});
$("body").append( tableView.render().$el );

还有一个小提琴http://jsfiddle.net/9avm6/5/

于 2012-04-26T08:10:14.860 回答