0

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/

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
bodokaiser
  • 15,122
  • 22
  • 97
  • 140
  • Why are you trying to recycle your `this.views`? Why not create and destroy the views as needed? – mu is too short Sep 02 '12 at 19:59
  • @muistooshort hi, i got two inconveniences about recreating views: 1. All data inserted in them is lost and I have to get it back some how. 2. I think it is better to reuse than to create but can be that this isn't true – bodokaiser Sep 03 '12 at 04:59
  • 1
    Views should be thin so throwing them away and recreating them should be cheap. If your views are fat then you should put their state in a model and track the model separately from the view. The problem with reusing views is, as you've seen, event binding is a mess. Your models don't have to correspond with the models on your server, models are just conveniently packaged hunks of data. – mu is too short Sep 03 '12 at 05:16
  • @muistooshort hi, I am doing something similar with a specific view of mine (an extra custom object for such work). But what is if you want to store a parent view with lots of nested views? – bodokaiser Sep 03 '12 at 13:14
  • 1
    Then you have to deal with the events the hard way. Or perhaps use `display` (or jQuery's `.show()` and `.hide()`) to manage your views instead of replacing blobs of HTML. – mu is too short Sep 03 '12 at 19:09
  • @muistooshort one last thing :) could you copy the comment as answer so I could mark it ? – bodokaiser Sep 04 '12 at 05:11

1 Answers1

0

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.

mvbl fst
  • 5,213
  • 8
  • 42
  • 59
  • take a closer look at the example. switch is triggered by the parent view on the button. The reinjected view is triggering an alert on click – bodokaiser Sep 03 '12 at 13:13