2

I want to use Backbone.js for some event handling things, but I am not confident about cyclical references & memory management. Let's say I have some static event source called EventStation - so, at the start of the script I say:

var source = new EventSource();

source is meant to live for the life of page and that's fine. Now, I also have an event consumer:

var EventConsumer = Backbone.Model.extend({
    initialize: function(params) {
        source.on("some_event",this.onSomeEvent,this);
    }
});

function later() {
    var consumer = new EventConsumer();

    // consumer now gets leaked... (I think)
}

I call later() at some point - and at the end, I no longer have any access to consumer, except if I go digging around through the internals of source. I think I need to add some new function to EventConsumer, like

cleanup: function() {
    source.off("some_event",this.onSomeEvent,this);
}

And then call that at the end of later().

This seems... not as clean as I would like it. Is there some way to do this better? Would this handle differently if I was using DOM events?

Daniel
  • 1,188
  • 11
  • 22

1 Answers1

5

Read this:

http://lostechies.com/derickbailey/2011/09/15/zombies-run-managing-page-transitions-in-backbone-apps/

While it specifically talks about views, it applies to any event binding object.

Also this:

Backbone.js : repopulate or recreate the view?

Johnny Oshika's idea for managing event binding and unbinding with his "bindTo" method and "unbindAll" method are brilliant. I highly recommend using these methods in an object that manages your events for you.

If you would like an implementation of this, I have it built in to my Backbone.Marionette framework, here:

https://github.com/derickbailey/backbone.marionette/blob/master/src/backbone.marionette.bindto.js

This code is MIT licensed open source, so you're free to copy it and use it wherever you want... no requirement to use Marionette just to get this functionality.

To use the BindTo object, you extend it in to your own object:


var source = _.extend({}, Backbone.Marionette.BindTo);

or use it as a prototype:


var source = Object.create(Backbone.Marionette.BindTo);

Then bind events passing the event source as the first parameter, with all the standard Backbone events args after that:


source.bindTo(myObj, "some_event", this.doStuff, this);

and to unbind everything,


source.unbindAll();

Documentation for my implementation can be found here:

https://github.com/derickbailey/backbone.marionette/blob/master/docs/marionette.bindto.md

Community
  • 1
  • 1
Derick Bailey
  • 72,004
  • 22
  • 206
  • 219