I’m facing with what looks like a zombie reference case.
First off, this is the code I’m working with.
Here you’ll find my User’s details manager layout gist
The controller, instead, can be found here
The flow of operations is as follow:
- Admin access the list of users upon hitting the route that calls “manageUsers” on the controller.
- Admin clicks on a user row and the event “users:selected” gets triggered and the listener recevies the user instance to work with.
- DetailsLayout gets instantiated and rendered in the application’s main layout. Specifically
in its “content” region. - The view that deals with user details form gets instantiated too and rendered inside
DetailsLayout’s “dettagli” region. - At this point, the administrator is interested in managing this user’s notes. So he clicks
on the tab labeled “notes” and the list of notes gets rendered in the DetailsLayout “note” region. - Clicking on the note the administrator wants to work with fires the event “notes:selected” which passes the note instance to the appropriate event handler (DetailsLayout.showNote).
At this point once the administrator clicks on the link that fires DetailsLayout.showUsers which, in turn fires the event “users:index” listened by the afore mentioned controller, he
gets back to point 1 of the list above.
Repeating the whole process up to point 5 works as expected but, as soon as the administrator
picks the note to work the debugger shows an error about the DetailsLayout region “note” not being defined.
Running through the code step by step I have found that on the second run the events fired are
correctly bound to the proper instance of DetailsLayout except for the point 6 which is still bound to the instance used on first pass.
The code above shows that each and every time the user’s details are shown a new instance of DetailsLayout gets created. Shouldn’t this be enough to guarantee that no zombies are still around? If I recall correctly from backbone.marionette documentation, each time layout.region.show() gets hit, it closes the previous view (unbinding events and all the rest) and attaches the newly passwed view.
What’s that I’m doing the wrong way?
Thanks in advance for your help.
Regards
P.S.
Backbone.marionette version is 0.8.4
Backbonejs version is 0.9.2
Your constructor in the UserDetailsList is the problem:
You’re directly binding to the
Hub.ventbut never explictly unbinding from these events. Therefore, your instance of UserDetails list is hanging around in memory forever.To fix this, you should use the layout’s
bindTomethod which will track the binding and unbind it for you when the layout’sclosemethod is called.Be sure to correctly close your layout when you no longer need it. Call the
closemethod on your layout instance. This will correctly clean up all of thebindToevents that the constructor set up.FYI – a
Layoutextends directly fromItemViewso all of the information / documentation about anItemViewalso applies to aLayout, including the use ofbindTo,close, etc.