Backbone.js按钮单击事件将针对按钮的所有实例触发,而不是仅针对单击的实例触发。为什么?

时间:2011-08-23 06:48:30

标签: javascript jquery dom backbone.js client-side-scripting

我正在学习backbone.js,我很新。我有一个视图作为按钮:

simpleButton = Backbone.View.extend({
     template: "<button class='${classes}'>${text}</button>",

     el: $("body"),

     events: {
         "click": "onClick",
         "focus": "onFocus",
         "blur": "onBlur"
     },

     initialize: function (args) {

         _.bindAll(this, 'render');
         this.rendered = false;
         this.text = args.text || 'button';
         this.classes = args.classes || [];
         this.classes.push('ui-button');
         //console.debug("Wh.views.simpleButton.initialize classes ",this.classes);
         if (args.autoRender === true) this.render();

     },

     render: function () {
         //console.debug("Wh.views.simpleButton.render classes ",this.classes);
         if (this.rendered === false) {
             $.tmpl(
                 this.template, {
                     classes: this.classes.join(' '),
                     text: this.text
                 }
             ).appendTo(this.el);
             this.rendered = true;
         }

     },

     //event handlers
     onClick: function (ev) {
         console.debug(this);
         alert("click on ", ev, this);
     },

     onFocus: function (ev) {
         ////console.debug(ev);
     },

     onBlur: function (ev) {

     }

 });

我的问题是,如果我创建两个按钮,然后单击其中一个按钮,我会收到警报框两次,调试显示“this”首先显示第一个按钮,然后显示第二个按钮。

我错过了什么吗?

4 个答案:

答案 0 :(得分:4)

您定义的事件将绑定到视图的“el”属性。在你的情况下它是“body”所以当你启动点击时,实例化了2个simpleButton视图,你有2个人正在监听同一个事件。

您实例化的每个视图应该代表el属性定义的一个且只有一个DOM元素。因此,如果您想创建一个按钮视图(不确定这是真实程序中的“最佳实践”),您可以:

SimpleButton =  Backbone.View.extend({
        template : "<button class='${classes}'>${text}</button>",

        tagName : "div", // defines the html tag that will wrap your template
        className: ".buttonbox", 
        ...
});

mybtn = new SimpleButton();
mybtn.render().appendTo('body')

这样,您的点击事件只会涉及按钮所在的div.buttonbox。

注意:渲染函数的骨干概念是创建一个html字符串,之后您将使用它来追加前置或DOM中的任何内容。这样,如果你创建了很多,你就可以这样做,所以你只刷新一次DOM(刷新DOM很贵)......

答案 1 :(得分:3)

在您的视图中使用此功能。它将取消绑定点击事件

initialize : function() {
    $(this.el).unbind("click");
}

答案 2 :(得分:1)

只是想到为应用程序中的每个按钮创建一个Backbone.View可能会导致性能过大,并且您无法利用jQuery中的“委托”功能。我改为为这些按钮的父元素创建一个Backbone.View。

当然,如果你有一些具有复杂逻辑的特殊按钮,那么他们可能应该得到他们自己的View类。 :)

答案 3 :(得分:0)

为您的按钮添加唯一的ID,例如<button id="button1"><button id="button2">,然后在您的事件哈希中,您需要指定点击事件您的按钮的ID想要处理该事件,例如:

events : {
        "click #button1" : "onClick",
        "click #button2" : "doSomethingElse"
    }

现在只有当你点击id = button1的按钮并且点击id = button2

的按钮时调用doSomethingElse()时,才会调用onClick()