admin管理员组文章数量:1429061
We have a single Backbone view prised of a sidebar and several sub-views. For simplicity, we've decided to have the sidebar and sub-views governed by a single render
function. However, the click .edit
event seems to be firing multiple times after clicking on one of the sidebar items. For example, if I start out on "general" and click .edit
, then hello
fires once. If I then click .profile
on the sidebar and click .edit
again, hello
fires twice. Any ideas?
View
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.");
},
Router
account: function(section) {
if (section) {
var section = section.toLowerCase();
}
app.view = new AccountView({model: app.user, section: section});
},
Solution
My solution was to change the router to this:
account: function(section) {
if (section) {
var section = section.toLowerCase();
}
if (app.view) {
app.view.undelegateEvents();
}
app.view = new AccountView({model: app.user, section: section});
},
This works for now, but will this create a memory leak?
We have a single Backbone view prised of a sidebar and several sub-views. For simplicity, we've decided to have the sidebar and sub-views governed by a single render
function. However, the click .edit
event seems to be firing multiple times after clicking on one of the sidebar items. For example, if I start out on "general" and click .edit
, then hello
fires once. If I then click .profile
on the sidebar and click .edit
again, hello
fires twice. Any ideas?
View
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.");
},
Router
account: function(section) {
if (section) {
var section = section.toLowerCase();
}
app.view = new AccountView({model: app.user, section: section});
},
Solution
My solution was to change the router to this:
account: function(section) {
if (section) {
var section = section.toLowerCase();
}
if (app.view) {
app.view.undelegateEvents();
}
app.view = new AccountView({model: app.user, section: section});
},
This works for now, but will this create a memory leak?
Share Improve this question edited Jul 23, 2013 at 23:40 David Jones asked Jul 23, 2013 at 23:08 David JonesDavid Jones 10.3k30 gold badges93 silver badges146 bronze badges 2- 1 If you post your router code, I can verify my hunch that you are creating duplicate view instances. – Peter Lyons Commented Jul 23, 2013 at 23:24
- Okay, I posted the relevant section of the router. – David Jones Commented Jul 23, 2013 at 23:28
3 Answers
Reset to default 6I had exactly the same problem when I first started using backbone. Like Peter says, the problem is that you have more than one instance of the View being created and listening for the event. To solve this, I created this solution in my last backbone project:
/* 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;
}
As you can see, it's always removing the last view and creating a new one, which then renders. I also add a require statement in the router because I don't want to have to load all views in the router until they are actually needed. Good luck.
Sounds like you are attaching multiple view instances to the same DOM element and they are all responding to the events. Are you making a new view each time you navigate without removing the previous view?
I have a dynamic view, that renders different templates inside the same element (about 12), based on router params. Now, the container in which the view renders, is defined inside the view.render() like so "el: '#some-container'". Naturally, i have to remove the view if it exists, before creating a new or the same one, to prevent zombies and s#!t. Just as a reminder, calling view.remove(), actually removes '#some-container' from the DOM, meaning the view has no place to render in, except for the first time. Now, there are dozens of methods to prevent this from happening. Just thought i should share in case anyone needs to save a few hours of research.
本文标签: javascriptBackbone events are firing multiple times after rerendering subviewsStack Overflow
版权声明:本文标题:javascript - Backbone events are firing multiple times after re-rendering sub-views - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1745529567a2661995.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论