admin管理员组文章数量:1221354
I am trying to build a switching view with backbone js and found out my bind event fired multiple times, when I switching view for few times.
Below is the code for 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 the red view for 3 times, and press 'click me'. It will pops up alert for 3 times as well. I suspect there's need to unbind the event somewhere, but couldn't find proper way to do it. Best to provide some references of doing this correctly.
Here's the link to jsfiddle demo. /
I am trying to build a switching view with backbone js and found out my bind event fired multiple times, when I switching view for few times.
Below is the code for 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 the red view for 3 times, and press 'click me'. It will pops up alert for 3 times as well. I suspect there's need to unbind the event somewhere, but couldn't find proper way to do it. Best to provide some references of doing this correctly.
Here's the link to jsfiddle demo. http://jsfiddle.net/mochatony/DwRRk/31/
Share Improve this question asked Jun 26, 2012 at 7:37 TonyTakeshiTonyTakeshi 5,92910 gold badges54 silver badges72 bronze badges 1- 1 You are not cleaning your views up, leaving you with ghost views. Check my answer below! – jakee Commented Jun 26, 2012 at 8:01
3 Answers
Reset to default 13Every time you click the red view
or blue view
-buttons you create a new Red or Blue View each and every time. You bind their events hash to respond to click DOM events originating from buttons with classes button
and button2
.
- Press 'red view' 3 times -> 3 instances of RedView created
- Click button with class 'button' -> DOM event
- 3 instances of RedView listening to said DOM event -> 3 alerts
This is because you don't clean the views before creating a new one effectively leaving you with ghost views that respond to events even though they can't be seen. (More info on the events hash) You can clean the events from you views with something like this.
cleanup: function() {
this.undelegateEvents();
$(this.el).clear();
}
Here is your fiddle with working cleanup of views http://jsfiddle.net/DwRRk/34/
Also a hint for good practice: you should use something like a render method to attach stuff to your DOM, use the initialize to just initialize the needed values for your view.
You are creating a new view everytime the buttons are clicked, without destroying the previous one. Try using a single view likes this:
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");
});
});
Here's another way of deleting 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 or else this won't work.
本文标签: javascriptBackbone bind event fired multiple timesStack Overflow
版权声明:本文标题:javascript - Backbone bind event fired multiple times - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1739323549a2158143.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论