[英]Backbone events are firing multiple times after re-rendering sub-views
我们有一个由侧边栏和几个子视图组成的Backbone视图。 为简单起见,我们决定让侧边栏和子视图由单个render
功能控制。 但是, click .edit
其中一个侧边栏项后, click .edit
事件似乎会多次触发。 例如,如果我从“general”开始并单击.edit
,那么hello
会触发一次。 如果我再单击.profile
的侧边栏,点击.edit
再次, hello
闪光两次。 有任何想法吗?
视图
events: {
"click .general": "general",
"click .profile": "profile",
"click .edit": "hello",
},
general: function() {
app.router.navigate("/account/general", {trigger: true});
},
profile: function() {
app.router.navigate("/account/profile", {trigger: true});
},
render: function(section) {
$(this.el).html(getHTML("#account-template", {}));
this.$("#sidebar").html(getHTML("#account-sidebar-template", {}));
this.$("#sidebar div").removeClass("active");
switch (this.options.section) {
case "profile":
this.$("#sidebar .profile").addClass("active");
this.$("#content").html(getHTML("#account-profile-template"));
break;
default:
this.$("#sidebar .general").addClass("active");
this.$("#content").html(getHTML("#account-general-template"));
}
},
hello: function() {
console.log("Hello world.");
},
路由器
account: function(section) {
if (section) {
var section = section.toLowerCase();
}
app.view = new AccountView({model: app.user, section: section});
},
解
我的解决方案是将路由器更改为:
account: function(section) {
if (section) {
var section = section.toLowerCase();
}
if (app.view) {
app.view.undelegateEvents();
}
app.view = new AccountView({model: app.user, section: section});
},
这现在有效,但这会造成内存泄漏吗?
当我第一次开始使用骨干时,我遇到了完全相同的问题。 就像Peter说的那样,问题在于你创建了多个View实例并正在监听事件。 为解决这个问题,我在上一个骨干项目中创建了这个解决方案:
/* Router view functions */
showContact:function () {
require([
'views/contact'
], $.proxy(function (ContactView) {
this.setCurrentView(ContactView).render();
}, this));
},
showBlog:function () {
require([
'views/blog'
], $.proxy(function (BlogView) {
this.setCurrentView(BlogView).render();
}, this));
},
/* Utility functions */
setCurrentView:function (view) {
if (view != this._currentView) {
if (this._currentView != null && this._currentView.remove != null) {
this._currentView.remove();
}
this._currentView = new view();
}
return this._currentView;
}
正如您所看到的,它总是删除最后一个视图并创建一个新视图然后呈现。 我还在路由器中添加了一个require语句,因为我不想在路由器中加载所有视图,直到实际需要它们为止。 祝好运。
听起来您正在将多个视图实例附加到同一个DOM元素,并且它们都响应事件。 您是在每次导航时创建新视图而不删除上一个视图吗?
我有一个动态视图,根据路由器参数在同一个元素(大约12个)内呈现不同的模板。 现在,视图呈现的容器在view.render()中定义,如“el:'#some-container'”。 当然,我必须删除视图,如果它存在,在创建一个新的或相同的,以防止僵尸和s#!t。 提醒一下,调用view.remove()实际上会从DOM中删除“#some-container”,这意味着视图无法呈现,除了第一次。 现在,有许多方法可以防止这种情况发生。 只是想我应该分享以防任何人需要节省几个小时的研究。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.