Help us understand the problem. What is going on with this article?

Viewに登録したイベントが複数回呼ばれてしまう場合の対処

More than 5 years have passed since last update.

以下のように、同じDOM要素に対して複数のBackboneのViewを適用すると、それぞれのイベントが残り続けてしまい、セレクタがかぶると二重にイベントが発生してしまいます。Viewがひとつの場合でも、Routerを使って同じViewを複数回表示した場合も同様です。

var AView = Backbone.View.extend({
    el: $("#main"),
    events: {
        "click button#btn1": "onBtn1Click"
    }
    ...
});
var BView = Backbone.View.extend({
    el: $("#main"),
    events: {
        "click button#btn1": "onBtn1Click"
    }
    ...
});

Backbone.Viewが持つremove()が使えるかと思ったのですが、DOM要素は消えてもイベント自体は残り続けていました。

この現象を解決するためには、Backbone.Viewが持つundelegateEvents()を呼び出す必要があります。別のViewに移動したタイミングで、

this.off();
this.undelegateEvents();
this.remove();

といった形でViewを破棄すると良いかと思います。

Backboneの実装を見たら

// Clears all callbacks previously bound to the view with `delegateEvents`.
// You usually don't need to use this, but may wish to if you have multiple
// Backbone views attached to the same DOM element.
undelegateEvents: function() {
    this.$el.off('.delegateEvents' + this.cid);
    return this;
},

と最初から書いてあった。困ったら実装見なきゃダメですね(^^;

matsukaz
株式会社カオナビCTO。SIer2社→サイバーエージェント→トランスリミットCTOを経験。「開発効率をUPする Git逆引き入門」「Slack入門」など執筆。AWS/Node.js/Ruby/Python/PHP/Go
http://matsukaz.hatenablog.com
kaonavi
クラウド人材管理ツール「カオナビ」の製造・販売・サポートを行い、企業の人材管理にイノベーションを起こすことを目的としている会社
https://www.kaonavi.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away