Search code examples
javascriptjquerydombackbone.jsbackbone-events

Re-inject Backbone.View into the DOM with keeping events instead of creating new events


I got following example Backbone.View:

var View = Backbone.View.extend({
  tagName: "div",

  className: "advertisement",

  initialize: function () {
    this.on('switch', this.
    switch, this);

    this.views = {};
    this.views.laptop = new LaptopAdView();
    this.views.piano = new PianoAdView();
    this.views.food = new FoodAdView();
  },

  render: function () {
    this.$el.empty();
    this.
    switch ('laptops');

    return this;
  },

  switch: function (ad) {
    var el;

    if (ad === 'laptop') {
      el = this.views.laptop.render().el;
    } else if (ad === 'piano') {
      el = this.views.piano.render().el;
    } else {
      el = this.views.food.render().el;
    }

    // reinsert the chosen view
    this.$el.empty().append(el);
    // bind all events new
    this.delegateEvents();
  }
});

As you see I use this.delegatEvents() to recreate all event bindings. This is actually not a perfect solution... It would be far better when I use this.$el.detach(); or an other method so I cache the whole object with its event instead of re-rendering and recreating all events.

Now with working fiddle: http://jsfiddle.net/RRXnK/66/


Solution

  • You are trying to bind to a Backbone view instead of a DOM element:

    this.on('switch', this.switch, this);

    It's all good, but who triggers 'switch' event? You do not have bindings that trigger DOM events, and this.delegateEvents(); only works on DOM events.

    Once you set up DOM events, e.g.

    this.$el.on('click', 'a', this.switch) -- 'switch' event will be triggered, and you will NOT have to re-delegate events as long as $el is in not removed from DOM.