消费行视图的骨干表视图 - 如何构建?

时间:2012-04-26 07:05:53

标签: javascript backbone.js backbone-views

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

我看到类似事情的常见方法是将每一行分解为它自己的视图,并且拥有一个父视图(在本例中可以说是表格)使用行视图生成要包含的html在你的代码中。但是我无法弄清楚它如何与模板一起使用。

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

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

示例代码(也在fiddle中):

/** 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();

谢谢!

1 个答案:

答案 0 :(得分:11)

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

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

  

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/