20

Coming from GWT, Backbone seems to miss a built-in solution on how to handle the life-cycle of a view. In GWT, every activity, which is more or less the equivalent to a View in Backbone, is managed by an ActivityManager which calls onStart/onStop on the activity, passing the eventBus and the element where the Activity can be rendered in. On stop, the ActivityManager will unbind all events the activity has bind to the eventbus and remove the view from the DOM.

In Backbone, it's easy to bind the events to model and collection but you have to remove them manually and there is no common api method where you will do this.

So I'm looking for best practice pattern on how to manage views to ensure no killed or disabled views are listening unnecessary to events.

skaffman
  • 381,978
  • 94
  • 789
  • 754
Andreas Köberle
  • 88,409
  • 51
  • 246
  • 277

4 Answers4

13

you are right, there is no build in solution to that (yet).

however it is of course possible to extend backbone to provide this functionality, Derick Bailey has written a blog post about this recently,

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

this is by no means the holy grail, you are free to implement as you wish, but it is a very straight forward approach, for handling zombie views, now you still need to take care of other creatures crawling in your memory, but this is a start with the views at least!

Sander
  • 12,991
  • 15
  • 70
  • 97
  • Nice article. Thanks for the link. – ProTom Dec 02 '11 at 07:31
  • Yes the article goes in the right direction, but after all the view is responsible for cleaning up. Im locking for a solution where the view dont care about cleaning up, cause someone else is doing it. Think about larger teams where sometimes someone forget to clean up manually. Also you have to write the same code over and over again. – Andreas Köberle Dec 02 '11 at 08:08
  • such a system does not exist with backbone, because they want to provide a structure that is and stays flexible, of course it's not unlikely someone has thought of this, and started a plugin, however i have not heard of one that does all of this automatically (yet). – Sander Dec 02 '11 at 09:06
  • @AndreasKöberle In the article, Derek extends the Backbone View prototype with a close() method which will unbind all events and remove the element from the view. Just have people use `view.close()` instead of `view.remove()` and then they can forget about cleaning up. – Eric Hu Dec 20 '11 at 21:54
  • @EricHu or just extend view.remove (either of the Backbone View or your own BaseView) – roberkules Mar 25 '12 at 02:52
5

I'm using a custom BaseView, which extends Backbone's remove method:

app.BaseView = Backbone.View.extend({

    views: [], // array to keep a ref of child-views for proper disposal later on

    remove: function() {

        // dispose any sub-views
        _.each(this.views || [], function(view) {
            view.remove();
        });

        // if the inheriting class defines a custom on-remove method, call it!
        _.isFunction(this.onRemove) && this.onRemove();

        // unbind all events from this view
        this.off();

        // finally, call Backbone's default remove method to
        // remove the view from the DOM
        Backbone.View.prototype.remove.call(this);
    }
}

There's still a catch: models and collections need to be disposed by hand, because you don't know if it's used by other views too.

roberkules
  • 6,389
  • 1
  • 40
  • 51
3

Seems Marionette finally has the functionality I'm looking for.

Andreas Köberle
  • 88,409
  • 51
  • 246
  • 277
2

I post my solution to manage view at https://github.com/thomasdao/Backbone-View-Manager.

The view manager will always cleanup existing view before create a new view. Now I will initialize a new view by:

newView = VM.createView("newView", function(){
             return new View();
          };

If I want to reuse a view instead of creating a new one, I can use

newView = VM.reuseView("newView", function() {
              return new View();
          }

The different between VM.reuseView and VM.createView is that, reuseView will look for existing view with name "newView", if found it will return to you. Else, it will execute the callback function and cache result. VM.createView will always execute the callback function and cleanup existing view for you. Hence you may like to use VM.createView if the views is dynamic and frequently change

thomasdao
  • 2,662
  • 1
  • 25
  • 23