主干表视图消费行视图 - 如何构建



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

我看到与此类似的一种常见方法是将每一行分解为它自己的视图,并让父视图(在本例中为表)使用行视图生成要包含在代码中的 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();

谢谢!

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

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

setElement view.setElement(element)

如果您想应用骨干 查看不同的 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/

最新更新