在Backbone.View的所有实例中触发事件

时间:2013-02-21 03:27:05

标签: backbone.js

我正在使用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上附加了一个click事件。

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

我首先想要的是将category name添加到rowTemplate并将DOM中的值与视图中的值进行比较,以查看哪一个实际触发了事件。

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

EXTRA:如果我只创建一个视图,并在模板中迭代以生成行,会被认为更好吗?

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

3 个答案:

答案 0 :(得分: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

答案 1 :(得分: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;
}

答案 2 :(得分: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()

        }
...