如何避免Backbonejs View中的双事件绑定?

时间:2016-02-05 18:32:45

标签: javascript backbone.js

var RowView = Backbone.View.extend({
    tagName: 'li',
    className: 'course-row',
    events: {
        "click .table-row": "rowClick" // problem here!
    },
    initialize: function() {},
    template: _.template(tpl),
    render: function() {

        var rowStr = this.template({course: this.model});
        $(this.el).append(rowStr);
    },
    rowClick: function (e) {
        alert(e);
    }
});

上面的代码定义了Backbone Row视图。我想在表格中创建和渲染几行,所以我做了:

data.forEach(function(rowData){
    var row = new RowView({model: course, el: mountPoint});
    row.render();
});

如果我创建了2行,则事件绑定两次(如果单击该行则为2 alert msg),3行3次。我通过在父视图中定义事件来避免此问题,但如果我真的需要在每一行附加事件处理程序,我该如何避免双事件绑定问题?

1 个答案:

答案 0 :(得分:2)

你这样做:

data.forEach(function(rowData){
    var row = new RowView({model: course, el: mountPoint});
    row.render();
});

这意味着您的观点会忽略其tagNameclassName,然后继续将自己绑定到您提供的el because

  

this.el可以从DOM选择器字符串或Element中解析出来;否则,它将从视图的tagNameclassNameidattributes属性中创建。

一个视图的events are bound to its el using delegation,您正在绑定多个视图(恰好是相同的视图"类")所以当然您获得了多个视图事件绑定。

如果你的行真的应该是<li class="course-row">元素,那么你想做几件事:

  1. RowView创建并拥有自己的el。将tagNameclassName属性保留在RowView中,然后停止将el传递给构造函数。您也应该将$(this.el)更改为this.$el,当Backbone已经为您隐藏了一个jQuery对象时,无需再创建另一个jQuery对象。

  2. this&#39; RowView返回render,这是标准做法,让下一步更好一些。

  3. 无论创建RowView的是什么,都应该创建它们,render,然后将它们放在容器中。您似乎尝试使用mountPoint(可能是<ul>}作为容器,因此您想说:

    data.forEach(function(rowData) {
        var row = new RowView({model: course});
        mountPoint.append(row.render().el);
        // This is why (2) above -----^^^
    });
    

    假设mountPoint是一个jQuery实例,如果情况并非如此,那么您想要代之以$(mountPoint).append(row.render().el)(或者执行var $mountPoint = $(mountPoint)以上forEach并在其中使用$mountPoint.append

  4. 个人经验法则:如果您将el传递给视图构造函数,那么您几乎肯定会犯错误。如果您确切知道为什么要将el传递给构造函数,知道后果,并知道如何处理它们,那么您已经足够成年,可以用剪刀运行,所以请直接前进。