Trunk binding event fires several times

I am trying to create a switch view using backbone js and found that the binding event is fired several times when I switch the view several times.

Below is the code for a better illustration:

HTML

<div id='container'> halo world </div> <button id='but1'>red view</button> <button id='but2'>blue view</button> 

CSS

 #red_view{ width:400px; height:400px; background-color:red; } #blue_view{ width:400px; height:400px; background-color:blue; } .button,.button2{ width:300px; height:300px; background-color:gray; } 

Javascript

 RedView = Backbone.View.extend({ el: "#container", events:{"click .button":"clickme"}, clickme:function(){ alert('redview'); }, initialize: function(){ this.$el.html("<div id='red_view'><div class='button'>Click Me</div></div>"); } }); BlueView = Backbone.View.extend({ el: "#container", events:{"click .button2":"clickme2"}, clickme2:function(){ alert('blueview'); }, initialize: function(){ this.$el.html("<div id='blue_view'><div class='button2'>Click Me</div></div>"); } }); $(document).ready(function(){ //var router = new SystemRouter(); $('#but1').click(function(){ var view = new RedView(); }); $('#but2').click(function(){ var view = new BlueView(); }); }); 

If you click on the red view 3 times and click "click me." It will also appear 3 times. I suspect that somewhere you need to untie the event, but could not find the right way to do this. It is best to give some recommendations regarding proper implementation.

Here is a link to jsfiddle demo. http://jsfiddle.net/mochatony/DwRRk/31/

+4
source share
3 answers

Each time you press the red view or blue view buttons, you create a new red or blue view each time. You associate a hash of their events with a response to clicking DOM events originating from buttons with button and button2 classes.

  • Click "red view" 3 times β†’ 3 instances of the created RedView
  • Press a button with class 'button' -> DOM event
  • 3 RedView instances listening on the specified DOM event -> 3 alerts

This is due to the fact that you do not clear representations before creating a new one, in fact leaving you with ghostly representations that react to events, even if they are not visible. (Additional information about hash events) You can clear events from your views like this.

 cleanup: function() { this.undelegateEvents(); $(this.el).clear(); } 

Here is your fiddle with a working view cleaning http://jsfiddle.net/DwRRk/34/

Also a tip for good practice: you should use something like a rendering method to attach the material to your DOM, use initialization to simply initialize the necessary values ​​for your view.

+11
source

You create a new view every time the buttons are pressed without destroying the previous one. Try using one view:

http://jsfiddle.net/DwRRk/32/

 var SomeModel = Backbone.Model.extend({}); var SomeView = Backbone.View.extend({ el: "#container", model: SomeModel, events: { "click .button": "clickme" }, clickme: function() { alert(this.model.get("color")); }, colorChanged: function() { this.$el.html("<div id='" + this.model.get("color") + "_view'><div class='button'>Click Me</div></div>"); }, initialize: function() { _.bindAll( this, "colorChanged" ); this.model.on("change:color", this.colorChanged ); this.model.on("reset", this.colorChanged ); } }); $(document).ready(function() { //var router = new SystemRouter(); var model = new SomeModel({color: "red"}), view = new SomeView({model: model}) $('#but1').click(function() { model.set("color", "red"); }); $('#but2').click(function() { model.set("color", "blue"); }); });​ 
+1
source

Here's another way to remove ghost views (what I'm using)

 disposeView: function(view){ Backbone.View.prototype.close = function () { this.unbind(); this.undelegateEvents(); }; /* --Destroy current view */ if(this.currentView !== undefined) { this.currentView.close(); } /* --Create new view */ this.currentView = view; this.currentView.delegateEvents(); return this.currentView; } disposeView(new view()); 

Be sure to always return "this" in your view, otherwise this will not work.

+1
source

All Articles