Question

Good day to all.

I'm writing an application using Marionette.js and recently I started noticing that moving from view to view and starting/stopping different modules memory consumption grows and not getting released. I started wondering whether I unbind my events correctly and whether I bind to them correctly as well.

So, I have the following cases

  1. Modules

My application consists of sub-applications (modules). When I define a module I do some binding to global event aggregator. Something like this:

MyApplication.module(...) {
    var api = { ... some functions here ... }

    // Binding to events
    MyApplication.vent.on('some:event', function() {...});
    MyApplication.vent.on('some:other:event', function() {...});
}

I have checked the documentation and understand that "on" is not a very good choice, I should probably use "listenTo":

MyApplication.module(...) {
    var api = { ... some functions here ... }

    // Binding to events
    this.listenTo(MyApplication.vent, 'some:event', function() {...});
    this.listenTo(MyApplication.vent, 'some:other:event', function() {...});
}

But, here is the question, when module gets stopped, does it call "stopListening" or some other internal method that unbinds all the events I have bound in it? I checked the source code of the marionette's module and documentation but, if I understood correctly, when stop is called I need to take care of unbinding everything myself. Am I right?

  1. Controllers

Can be initialized and closed. From the documentation I see that:

Each Controller instance has a built in close method that handles unbinding all of the events that are directly attached to the controller instance, as well as those that are bound using the EventBinder from the controller.

Does it mean that if do the following I correctly unbind all of the events I bound in the controller? I guess the answer is yes.

MyApplication.module(...) {
    var controller = Marionette.Controller.extend({
        ...

        // This will be unbinded as I understand?
        this.listenTo(someObject, 'some:event', _.bind(function() {

            // This will also be unbinded
            this.listenTo(someOtherObject, 'some:event', function() {

                // This won't be, because in this case this is not in a "controller"
                // context but in a function's context which wasn't bound to "controler"
                // context.
                this.listenTo(some3rdObject, 'some:event', function() { ... });

            });

        }, this));
    });

    // Create controller when this sub-application gets initialized.
    Contents.addInitializer(function () {
        MyModule.Controller = new controller();
    });

    // Destroy controller and unbind all its event handlers.
    Contents.addFinalizer(function () {
        MyModule.Controller.close();
        delete Contents.Controller;
    });
}

So, with controllers I don't need to do anything as long as I use "listenTo", correct?

  1. Views

In views, according to documentation, all gets unbinded when the view gets closed. And again, as long as I use

this.listenTo(..., 'some:event', function() {...});

I should be ok, correct?

To summarize... I only need to take care of unbinding in module's stop event, in all other cases it is taken care of by marionette's core as long as I don't use direct "on" and use "this.listenTo" instead.

Thank you all very much in advance for your answers.

Was it helpful?

Solution

Controllers and Views do their cleaning work correctly but Modules doesn't do it.

Here is more detailed info:

  1. Controller

    If you close controller it will unbind all events that are bonded using listenTo in context of controller. You can look in in controller source code.

  2. View

    According to Backbone.View source code remove method does stopListening. Also Marionette.View's close calls backbone's remove under the hood. Here is source code.

  3. Module

    I've checked Marionette.Module source code but there is no stopListening in stop method. So, Marionette.Module#stop does not do unbinding of events and you should do it manually in finalizer or in onStop, onBeforeStop handlers.

    UPDATED: After Marionette.js v1.7.0 Marionette.Module calls stopListening on stop to unbind all events.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top