javascript - Backbone events are firing multiple times after re-rendering sub-views -
we have single backbone view comprised of sidebar , several sub-views. simplicity, we've decided have sidebar , sub-views governed single render
function. however, click .edit
event seems firing multiple times after clicking on 1 of sidebar items. example, if start out on "general" , click .edit
, hello
fires once. if click .profile
on sidebar , click .edit
again, hello
fires twice. 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 change router 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 now, create memory leak?
i had same problem when first started using backbone. peter says, problem have more 1 instance of view being created , listening event. solve this, created solution in 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 can see, it's removing last view , creating new one, renders. add require statement in router because don't want have load views in router until needed. luck.
Comments
Post a Comment