backbone remove view deletes the el
Asked Answered
G

2

24

I am creating a single page application, and I am quite new to backbone. I have a problem with creating multiple views which uses the same wrapper-div.

My setup:

I have added a close function to all views:

Backbone.View.prototype.close = function(){
    this.remove();
    this.off();
    if (this.onClose){
        this.onClose();
    } 
}

I have a wrapper-div where I want to render views, remove them and render new ones. So my SetupView looks like this:

app.SetupView = Backbone.View.extend({
    el: '#my_view_wrapper',
    ...
});

From the function where I swap views I close the current (open) view like this:

var v = this.model.get('view');
v.close();

Question

My problem is that I have multiple view's using the same wrapper-div. But when I close a view, this wrapper-div seems to be removed, and the next view I try to create can't find this div.

I guess there is an easy solution? I want to reuse the same wrapper, and only remove the view inside it, not the wrapper itself.

Godavari answered 29/12, 2012 at 16:39 Comment(4)
remove removes the element from the DOM. But I think I misunderstood el. I thought it just was the place the new element got injected, but have now learned that it becomes a part of the new element, and therefor it is removed when i call remove.Godavari
Right. You're generally better off letting each view manage its own el: the view should create its el, do things to it, and remove it when the view is removed. The caller puts the view's el inside a container that the caller controls. Not re-using DOM elements for multiple views helps you avoid a lot of problems.Congratulate
@muistooshort - good advice. never thought about this - makes perfect sense. thank you.Mcclain
@Mcclain Yeah, it solves so many problems and simplifies everything, I don't know why people do it any other way.Congratulate
K
17

In your scenario don't use an existing DOM element as your "el" value. Backbone will create the element for you. When you instantiate your view you can do the following to attach it to your existing wrapping element.

$(viewName.render().el).appendTo('#my_view_wrapper');
Kerrison answered 29/12, 2012 at 17:24 Comment(0)
A
25

Just as an addition (for later reference) : another option is to overwrite the subviews remove so that it just empties $el instead of removing it. Eg.

remove: function() {
      this.$el.empty().off(); /* off to unbind the events */
      this.stopListening();
      return this;
}

Personally I prefer this, as it removes the need to insert wrapper elements that have no real use.

Attila answered 25/9, 2013 at 11:22 Comment(3)
I agree. this method should be built into Backbone, switching between empty and remove based on whether an el is declared or not.Connecticut
I would also add this.$el.empty().off() as well to make sure all events are turned off.Connecticut
For reference, Backbone's implementation is here.Diggins
K
17

In your scenario don't use an existing DOM element as your "el" value. Backbone will create the element for you. When you instantiate your view you can do the following to attach it to your existing wrapping element.

$(viewName.render().el).appendTo('#my_view_wrapper');
Kerrison answered 29/12, 2012 at 17:24 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.