powmedia / backbone.xview

Easy to use view manager for Backbone. Effortless nested views and templating.
MIT License
10 stars 3 forks source link

Zombie View creation with addView #4

Closed mulderp closed 10 years ago

mulderp commented 10 years ago

Hi,

I am stuck with a simple looking thing.

I had 1 view added and removed dynamically to the layout:

  setDetails: function(movie) {
    if (this.currentDetails) {
      this.removeView(this.currentDetails);
      this.render();
    }
    var view = new DetailsView({model: movie});
    this.addView('#details', {id: view.cid}, view);
    this.currentDetails = view.cid;
  }

So far, and re-rendering was working great. Now, I've added a 3rd view like this:

    this.addView('#overview', new MoviesList({
      collection: options.router.movies,
      router: options.router
    }));
    this.addView('#controls', new Controls({
      collection: options.router.movies
    }));

and also tried the unwrap mode:

    Backbone.$('#controls').html((new Controls({
      collection: options.router.movies
    })).render());

Strangely, after the first adding/removing of a view in the layout, the control view becomes a zombie view. Any ideas how to debug this? That would be great, thanks!

mulderp commented 10 years ago

The situation is also here: https://github.com/pipefishbook/ch_5/tree/zombie_bug/sortui

powmedia commented 10 years ago

One thing I noticed, is you need to pass the view el to jQuery:

Backbone.$('#controls').html((new Controls({
      collection: options.router.movies
    })).render().el);
mulderp commented 10 years ago

Thanks, I tried that too, but maybe it is a good start for debugging. Let's first set:

    var controls = new Controls({ collection: options.router.movies });
    debugger
    Backbone.$('#controls').html(controls.render().el);

When I check controls, I get:

> controls.render().el
<p>​Sort:​</p>​
> controls.template()
"<p>Sort:</p>        <button id="by_title">By Title</button>  <button id="by_rating">By Rating</button>    <button id="by_showtime">By Showtime</button>  
mulderp commented 10 years ago

When I leave unwrap out, I get:

> controls.render().el
<p>Sort:</p>
   <button id="by_title">By Title</button>
   ...

But since the element is re-rendered, I get a zombie view later.

powmedia commented 10 years ago

I'm not sure what you mean however when using unwrap the template must have a root element (e.g. wrap the p and button in a div)

mulderp commented 10 years ago

Hmm.. ok, I can make my controls div work by using the idea from unwrap directly:

     var controls = new Controls({ collection: options.router.movies });
     controls.setElement(Backbone.$('#controls'));

Probably there is a nicer way with the addView approach, but it'll do for now. Thanks for the feedback!

mulderp commented 10 years ago

Ah, this looks already close to what I was looking for:

  onRender: function() {
    this.controls.setElement($('#controls'));
  },

  initialize: function(options) {
    this.addView('#overview', new MoviesList({
      collection: options.router.movies,
      router: options.router
    }));
    this.controls = new Controls({ collection: options.router.movies });
  }
mulderp commented 10 years ago

What do you think? It is a bit the idea of addView or? The only difference is that the view is not dynamically added right now, which is fine when it is included in parent template.

mulderp commented 10 years ago

The working example is at: http://pipefishbook.com/ch_5/sortui/#