Search code examples
javascriptbackbone.js

How to properly destroy view on backbone?


So Im new at backbone, and Im trying to make a single page app, Im using routes to manage certain things, and I want to remove a view when the user gets to another route

Im using this method to destroy the view

destroy_view: function() {

    // COMPLETELY UNBIND THE VIEW
    this.undelegateEvents();

    this.$el.removeData().unbind(); 

    // Remove view from DOM
    this.remove();  
    Backbone.View.prototype.remove.call(this);

}

also this is my route element

Router = Backbone.Router.extend({
        routes: {
            '':'index',
            '#':'index',
            'events/*event' : 'events'
        },
        index: function(){
            this.indexView = new VistaIndex();
        },
        events: function(params) {
            if( this.indexView )
                this.indexView.destroy_view()
            this.eventView = new EventView({currentEvent: params})
        }
    });

the problem with this is that if I do this the app crashes, so what do you recommend me to do :)


Solution

  • Here’s how I do it:

      Backbone.View.extend({
          //some other view stuff here...
          destroy: function () {
              this.undelegateEvents();
              this.$el.removeData().unbind();
    
              this.remove();
              //OR
              this.$el.empty();
          }
      });
    

    First we want to make sure we’re removing all delegated events (the ones in the events:{"event selector": "callback"} hash). We do this so we can avoid memory leaks and not have mystery bindings that will fire unexpectedly later on. undelegateEvents() is a Backbone.View prototype function that removes the view’s delegated events. Simple.

    Next we want to cleanup any data in the view object that is hanging around and unbind any events that we bound outside the events hash. jQuery provides a removeData() function that allows us to to do that. You may also have bound event listeners to your view chain unbind() with no arguments to remove all previously-attached event handlers from your $el. this.$el.removeData().unbind();

    Now you may want to do one of two things here. You may want to remove your view element completely OR you just want to remove any child elements you’ve appended to it during it’s life. The latter would be appropriate if, for example, you’ve set the $el of your view to be some DOM element that should remain after your view behavior is complete

    In the former case, this.remove() will obliterate your view element and it’s children from the DOM.

    In the later case, this.$el.empty() will remove all child elements.

    Check out this fiddle if you want to fool around with my solution. http://jsfiddle.net/oakley349/caqLx10x/