我遇到的问题是点击事件不断堆积(更改视图后仍然附加)。我通过只有一个视图实例(如下所示)解决了这个问题。我认为当标记改变时,脊柱会消除事件。我对其他观点没有这个问题。
BROKEN CODE:随着更多视图的创建,点击事件会继续堆积在loadPlayerCard上。
//Player Thumb View
PgaPlayersApp.PlayerThumbView = Backbone.View.extend({
events: {
'click': 'loadPlayerCard'
},
tagName: 'li',
template: _.template( $('#player_thumb').html()),
render: function()
{
this.$el.html(this.template(this.model.toJSON()));
return this;
},
loadPlayerCard: function()
{
new PlayerCardView({model: this.model}).render();
return false;
}
});
//Router
var Router = Backbone.Router.extend({
routes:{
'': 'loadPlayers'
},
loadPlayers: function()
{
PgaPlayersApp.Players.fetch({reset: true, success: function()
{
//When players is first fetched, we want to render the first player into the card area
new PlayerCardView({model: PgaPlayersApp.Players.first()}).render();
}});
}
});
PgaPlayersApp.Router = new Router();
Backbone.history.start();
固定代码:解决问题的代码:
PgaPlayersApp.CurrentPlayerCard = new PlayerCardView();
//Player Thumb View
PgaPlayersApp.PlayerThumbView = Backbone.View.extend({
events: {
'click': 'loadPlayerCard'
},
tagName: 'li',
template: _.template( $('#player_thumb').html()),
render: function()
{
this.$el.html(this.template(this.model.toJSON()));
return this;
},
loadPlayerCard: function()
{
PgaPlayersApp.CurrentPlayerCard.model = this.model;
PgaPlayersApp.CurrentPlayerCard.render();
return false;
}
});
//Router
var Router = Backbone.Router.extend({
routes:{
'': 'loadPlayers'
},
loadPlayers: function()
{
PgaPlayersApp.Players.fetch({reset: true, success: function()
{
//When players is first fetched, we want to render the first player into the card area
PgaPlayersApp.CurrentPlayerCard.model = PgaPlayersApp.Players.first();
PgaPlayersApp.CurrentPlayerCard.render();
}});
}
});
PgaPlayersApp.Router = new Router();
Backbone.history.start();
PlayerCardView(供参考):
var PlayerCardView = PgaPlayersApp.PlayerCardView = Backbone.View.extend({
events: {
'click': 'flipCard'
},
el: '#pga_player_card',
template: _.template( $('#player_card').html()),
render: function()
{
this.$el.html(this.template(this.model.toJSON()));
return this;
},
flipCard: function()
{
this.$("#player_card_container").toggleClass('flip');
}
});
答案 0 :(得分:0)
在路由器中,您不断创建新的PlayerCardView
:
new PlayerCardView({model: PgaPlayersApp.Players.first()}).render();
所有这些观点都完全相同el
:
el: '#pga_player_card'
所以你不断创建新的PlayerCardView
,每个人都绑定到#pga_player_card
。
每次执行此操作时,都会将全新视图绑定到完全相同的DOM元素,并且每个视图都会调用delegateEvents
来绑定事件处理程序。请注意,delegateEvents
绑定到el
和jQuery's html
method:
在使用新内容替换这些元素之前,从子元素中删除其他构造(如数据和事件处理程序)。
因此html
对el
不执行任何操作,但它会从子元素中删除事件处理程序。请考虑使用<div id="d"></div>
:
$('#d').on('click', function() {
console.log('Before .html');
});
$('#d').html('<p>Where is pancakes house?</p>');
$('#d').on('click', function() {
console.log('After .html');
});
如果您再点击#d
,您将在控制台中看到前后消息。
这个简单的例子或多或少等同于你正在做的事情。
如果你有更好的时间:
#pga_player_card
内,让路由器执行$('#pga_player_card').append(view.render().el)
。view.remove()
。避免尝试为多个视图实例重用DOM元素,避免尝试重用视图,这也不值得麻烦。