24
votes

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.

2
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.swenedo
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.mu is too short
@muistooshort - good advice. never thought about this - makes perfect sense. thank you.cheshireoctopus
@cheshireoctopus Yeah, it solves so many problems and simplifies everything, I don't know why people do it any other way.mu is too short

2 Answers

17
votes

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');
25
votes

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.