0

我正在显示带有 Backbone 的类别表。我创建了两个视图:

  • RowView(包含单个 tr)
  • TableView(包含表结构)

定义:

RowView = Backbone.View.extend({
  el: "#content table tbody",
  initialize: function() {
    this.render();
  },
  render: function(){
    var params = { name: this.model.get('name'), route: this.options.route };
    var template = _.template( $("#rowTemplate").html(), params);
    this.$el.append(template);
  },
  events: {
    "click #name": "clickHandler"
  },
  clickHandler: function( event ) {
    console.log('Browse subcategories of ' + this.model.get('name'));
  }
});

TableView = Backbone.View.extend({
  el: "#content",
  initialize: function(){
    this.render();
  },
  render: function(){
    var row = new this.collection();
    var that = this;
    row.fetch({
      success: function() {
        console.log('Collection fetch succeeded');
        var params = { title: that.options.title,
                       counter: row.at(0).get('counter'),
                       route: that.options.route
                     };

        var template = _.template( $("#tableTemplate").html(), params);
        that.$el.html( template );
        // RowView's are created by iteration here
        for(var x = 1; x < row.length; x++) {
          var params = { model: row.at(x), route: that.options.route };
          var view = new RowView(params);
        }
      }
    });
  }
});

如您所见,我在 RowView 上附加了一个点击事件。

行视图模板:

<script type="text/template" id="rowTemplate">
<tr>
  <td id="name" class="fill"><%= name %></td>
  <td><a href="#<%= route %>/<%= name %>/edit" class="btn">Editar</a></td>
</tr>
</script>

单击任何#name会在视图的所有实例中触发处理程序。因此,当单击一个类别时,我得到:

Browse subcategories of category1 127.0.0.1:68
Browse subcategories of category2 127.0.0.1:68
etc...

据我所知,那是因为所有人RowView's都被委派给同一个el.

我想到的第一件事是将DOM 中category namerowTemplate值与视图中的值进行比较,以查看哪个实际触发了事件。

但这种解决方案看起来真的很难看。完成此操作的正确方法是Backbone什么?

额外:如果我只创建一个视图并在模板中迭代以生成行,是否会更好?

编辑:我认为提供的代码就足够了。否则我可以添加它们。

4

3 回答 3

1

你可以RowView这样修改:

RowView = Backbone.View.extend({
    container: '#content table tbody',
    tagName: 'tr',
    initialize: function() {
        this.render();
    },
    render: function() {
        var params = {
            name: this.model.get('name'),
            route: this.options.route
        };
        var template = _.template($("#rowTemplate").html(), params);
        this.$el.html(template).appendTo(this.container);
    },
    events: {
        "click .fill": "clickHandler"
    },
    clickHandler: function(event) {
        console.log('Browse subcategories of ' + this.model.get('name'));
    }
});

和 RowView 模板:

<script type="text/template" id="rowTemplate">
<td class="fill"><%= name %></td>
<td><a href="#<%= route %>/<%= name %>/edit" class="btn">Editar</a></td>
</script>

Backbone.js 将创建一个tr元素。然后用模板this.$el.html(template).appendTo(this.container)填充tr元素并附加到#content table tbody.

就像这样,RowView 的事件被委托给 RowView 的 el,而不是#content table tbody.

于 2013-02-21T03:50:51.887 回答
0

尝试这个

RowView = Backbone.View.extend({
    container: '#content table tbody',
    tagName: 'tr',


  //  initialize: function() {
 //           this.render();
 //       },
    render: function() {
        var params = {
            name: this.model.get('name'),
            route: this.options.route
        };
        var template = _.template($("#rowTemplate").html(), params);
        this.$el.append(this.template);
    },
    events: {
        "click .name": "clickHandler"
    },
    clickHandler: function(event) {
        console.log('Browse subcategories of ' + this.model.get('name'));
    }
});

RowView 模板(无需识别每个行视图):

<script type="text/template" id="rowTemplate">
<td class="name"><%= name %></td>
<td><a href="#<%= route %>/<%= name %>/edit" class="btn">Editar</a></td>
</script>

然后是表格视图:

...
       that.$el.html( template );
        // RowView's are created by iteration here
        for(var x = 1; x < row.length; x++) {
          var params = { model: row.at(x), route: that.options.route };
          var view = new RowView(params);
          that.$el.find('tbody').append(view.el);
          view.render()

        }
...
于 2013-02-21T06:00:16.343 回答
0

您的页面上有多个具有相同 id 的元素,因为您的所有行都具有

<td id="name" class="fill">元素。

元素 ID 在您的文档中应该是唯一的。

一种解决方案是区分模板中的行,并使用事件作为函数来设置正确的 ID。

模板:

<script type="text/template" id="rowTemplate">
<tr>
  <td id="name-<%= name %>" class="fill"><%= name %></td>
  <td><a href="#<%= route %>/<%= name %>/edit" class="btn">Editar</a></td>
</tr>

事件功能:

events: function(){
  _events = {};
  _events["click #name-" + this.model.get('name')] = "clickHandler";
  return _events;
}
于 2013-02-21T05:22:03.600 回答