Skip to content

Nested views

Tim Branyen edited this page Mar 4, 2015 · 9 revisions

There are many ways to work with a View hierarchy relationship.

It's important to note here that all Layouts and managed Views are identical, the only difference is semantics.

Setting

The following method simply adds views into the virtual hierarchy. This means they will not be visible until you render, which you need to do yourself.

Using views object

Every View can have a views property which is an object that contains nested Views. This is a very declarative approach:

Backbone.Layout.extend({
  views: {
    "header": new HeaderView(),
    "section": new ContentView(),
    "footer": new FooterView()
  }
});

Dynamically setting a single View

When you want to set a View or replace an existing View in a given selector, you can use the setView method:

myLayout.setView("header", new HeaderView());

Appending directly to parent

Using the empty selector "" will insert a view directly into a parent using appendChild.

Backbone.Layout.extend({
  views: {
    "": new ContentView()
  }
});
// Or...
myLayout.setView("", new ContentView());
// Or... (in the case of the empty selector, 
// setView and insertView are identical)
myLayout.insertView("", new ContentView());

Inserting

Inserting a single View is useful for rendering collections and injecting one off modal-style Views.

Using views object

You can set multiple Views to be inserted by using an Array in the views object.

Remember that an empty string for the region name "" will insert directly into the parent.

Backbone.Layout.extend({
  views: {
    "": [
      new HeaderView(),
      new ContentView(),
      new FooterView()
    ]
  }
});

Dynamically inserting Views

Very useful when paired with beforeRender:

Backbone.View.extend({
  beforeRender: function() {
    this.collection.each(function() {
      this.insertView(new ListItemView());
    }, this);
  }
});

Getting

Once you've created a nested View relationship, it may be desirable to get access to the View object. There are many ways of doing this, which you can see in the Properties and Methods documentation.

// The most basic form of getting a View is passing a selector name, this will
// always return a single View.
var someView = myLayout.getView(".some-selector");

// If you have many Views under the selector, from `insertView`, you can use
// `getViews` instead.  This returns an underscore wrapped array of Views.
myLayout.getViews(".another-selector").each(function(view) {
  // Do something with the nested View.
});

// The last way is providing an Object, which internally uses `_.where`.
var someView = myLayout.getView({ template: "some-template" });

Removing

This method works similar to getView except that you will remove any View and its nested Views as well.

myLayout.removeView(".some-selector");