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

发布于 2024-12-01 01:51:56 字数 1435 浏览 1 评论 0原文

我正在学习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”的调试首先显示第一个按钮,并且接下来是第二个按钮。

我错过了什么吗?

I am learning backbone.js and am quite new. I have a view that acts as a button:

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) {

     }

 });

My problem is that if I create two buttons, and click just one of them, I get the alert box two times, and the debug showing me "this" shows the first button first, and the second button next.

Am I missing something?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

等风来 2024-12-08 01:51:56

您定义的事件绑定到视图的“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 字符串,您将在之后使用它来附加 prepend 或 DOM 中的任何内容。这样,如果您创建了很多,那么您只需刷新 DOM 一次(刷新 DOM 的成本很高)...

The events you define are bound to the "el" property of your view. In your case it is "body" so when you fire up click with 2 simpleButton views instantiated, you have 2 of them listening for the same event.

Each view you instantiate should represent one and only one DOM element defined by the el property. So if you want to create a button view (not sure this is 'best practice' in a real program) you could have :

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')

That way your click event will only concern the one div.buttonbox inside of which your button lives.

Notice : Backbone idea of the render function is creating an html string you'll use afterwards to append prepend or whatever in the DOM. That way if you create many you can do it so you only refresh the DOM once (refreshing the DOM is expensive)...

ぶ宁プ宁ぶ 2024-12-08 01:51:56

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

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

Use this in your View .it will unbind the click events

initialize : function() {
    $(this.el).unbind("click");
}
不忘初心 2024-12-08 01:51:56

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

当然,如果您有一些具有复杂逻辑的特殊按钮,那么它们可能确实值得拥有自己的 View 类。 :)

Just a thought that creating a Backbone.View for each and every button in your app could be a performance overkill and you can't leverage the "delegate" feature in jQuery. I'd instead create a Backbone.View for the parent element of those buttons instead.

Of course, if you have a few special buttons with complicated logic then they probably do deserve their own View classes. :)

活雷疯 2024-12-08 01:51:56

为您的按钮提供唯一的 ID,例如

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

现在只有当你点击id=button1的按钮并调用时才会调用onClick() doSomethingElse() 当你单击 id=button2 的按钮

Give your buttons unique ids, for example <button id="button1"> and <button id="button2">, then in your events hash, you need to specify the click event and the id of the button you want to handle that event for, e.g:

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

Now this will call onClick() only when you click on the button with id=button1 and call doSomethingElse() when you click on the button with id=button2

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文