Backbone.EventBinder: Better Event Management For Your Backbone Apps
One of my most popular blog posts in recent history is my Zombies! RUN! post where I outline the possibility and problem of memory leaks and “zombie” views and other objects in Backbone applications. There’s a good chance, in fact, that if you’ve built a Backbone application, you’ve read this article already. It seems to get more traffic and more “THANK YOU!!!!” responses than any other blog post (and rightfully so, IMO).
Down in the comments of that post, Johnny Oshika posted a link to his solution for managing events. I fell in love with that approach almost as soon as I saw it, and baked it in to Backbone.Marionette. Over the last year, then, it has grown and evolved a little and become a solution that I rely on to help me manage events in Marionette and in my backbone app development. I even baked it’s use directly in to every Marionette view, to handle the zombie view problems. I’ve had a lot of people ask how I manage zombies in Marionette, and I always point them to this solution. I’ve also had a number of people ask if they could use that solution outside of Marionette – YES! definitely. You should use this solution in any Backbone application that attached to events!
And now it’s even easier to use this in your app, even if you’re not using Marionette.
I recently extracted Backbone.EventBinder from Marionette and turned it in to it’s own repository in the MarionetteJS Github org, so that anyone and everyone building Backbone applications can take advantage of this without having to re-write it in their app.
From the EventBinder wiki:
When To Use Backbone.EventBinder
The general guidelines is that any time you have an object that is created and destroyed throughout the life of the application, and that object needs to bind to events from some other object, you should use the `EventBinder`.
Views And Memory Leaks
Views are the perfect example of this. Views get created and destroyed all the time. They also bind to a lot of different events from both the `model` and `collection` on the view. When the view is destroyed, those events need to be cleaned up. By using the built-in `bindTo` method on the view, the event handlers will be cleaned up for you. If you don’t use `bindTo` and instead use `on` directly, you’ll have to manually call `off` to unbind the events when the view is closed / destroyed. If you don’t, you’ll end up with zombies (memory leaks).
If you haven’t read them yet, check out these articles:
Custom Event Groupings
Views are not the only place that this applies, though, and not the only use case for `EventBinder`.
If you are working with handful of objects, binding to their events, and those objects can be replaced with other object instances, then an `EventBinder` would be useful. In this case, think of the EventBinder as a collection or group of events for related objects.
Let’s say you have ObjA, ObjB and ObjC. Each of these fires some events, and you want to make sure you clean up the event handlers when your code is done. This is easy with an `EventBinder`:
Calling `stop` in this code will properly clean up all the event handlers for this use.
When To Use on/off Directly
The converse to all of this, is to say that you don’t always need to use an `EventBinder`. You can get away without it, always. But you need to remember to clean up your events when necessary.
In situations that do not need event handlers to be cleaned up, there is no need to use an `EventBinder`, as well. This may be an event that a router triggers, or that the `Marionette.Application` object triggers. For those application lifecycle events, or events that need to live throughout the entire life of the app, don’t bother with an `EventBinder`. Instead, just let the event handlers live on. When the person refreshes the browser window, or navigates to a different site, the handlers will be cleaned up at that point.
But when you need to manage your memory and event handlers, cleaning up references and closing things down without refreshing the page or navigating away from it, then `EventBinder` becomes important as it simplifies event management.
Marionette & EventBinder
The EventBinder is still a critical and foundational part of Marionette, of course. We’re in the process of changing up how Marionette’s build and deployment process works, slightly, to account for this being an external resource. But Marionette will still make heavy use of the EventBinder, as it always has. We’re also working to make sure these changes are as simple as possible for everyone – for those who just want to use some of Marionette’s building blocks, for those contributing to Marionette, for those that are new to it and want an all-in-one download of Marionette, and for the advanced users of Marionette who want piece everything together and upgrade different parts as needed.
It’s a bit of a challenge to do this, but I think we have a good plan. Be sure to keep an eye on the Marionette website in the next month or so as we head toward this.