Skip to content

Multiple Named Views

timkindberg edited this page Mar 4, 2013 · 11 revisions

You can name your views so that you can have more than one ui-view per state. Let's say you had an application state that needed to dynamically populate a graph, some table data and filters for the table like this: Multiple Named Views Mockup

When setting multiple views you need to use the views property on state. views is an object. The property keys on views should match your view names, like so:

<!-- somereportthing.html -->
<body>
  <div ui-view="filters"></div>
  <div ui-view="tabledata"></div>
  <div ui-view="graph"></div>
</body>
$stateProvider
  .state('report', {
    views: {
      'filters': { ... templates, controllers, resolve, etc ... },
      'tabledata': {},
      'graph': {},
    }
  })

Then each view in views is can set up its own templates, controllers, and resolve data.

$stateProvider
  .state('report',{
    views: {
      'filters': {
        templateUrl: 'report-filters.html',
        controller: function($scope){ ... controller stuff just for filters view ... }
      },
      'tabledata': {
        templateUrl: 'report-table.html',
        controller: function($scope){ ... controller stuff just for tabledata view ... }
      },
      'graph': {
        templateUrl: 'report-graph.html',
        controller: function($scope){ ... controller stuff just for graph view ... }
      },
    }
  })

View Names

Every view gets assigned an absolute name that follows a scheme of viewname@statename, where viewname is the name used in the view directive and state name is the state's absolute name, e.g. contact.item. The previous example could also be written as such:

  .state('report',{
    views: {
      'filters@report': {
        templateUrl: 'report-filters.html',
        controller: function($scope){ ... controller stuff just for filters view ... }
      },
      ... other views ...

Notice that the view name is now specified as the absolute name, as opposed to the relative name. It is targeting the 'filters' view located in the 'report' state. This let's us do some powerful view targeting. Let's assume we had several nested views set up like this (this example is not realistic, its just to illustrate view targeting):

<!-- index.html -->
<body ng-app>
<div ui-view></div> <!-- Assume contacts.html plugs in here -->
<div ui-view="status"></div>
</body>
<!-- contacts.html -->
<h1>My Contacts</h1>
<div ui-view></div>
<div ui-view="detail"></div> <!-- Assume contacts.detail.html plugs in here -->
<!-- contacts.detail.html -->
<h1>Contacts Details</h1>
<div ui-view></div>
<div ui-view="info"></div>

Let's look at the various views you could target from within the contacts.detail state. Remember that if an @ is used then the view path is considered absolute:

$stateProvider
  .state('contacts.detail', {
    templateUrl: 'contacts.detail.html'
    views: {
        "info" : {}            // relatively targets the "info" view in "contacts.detail" state
        "" : {}                // relatively targets the unnamed view in "contacts.detail" state
        "detail@contacts" : {} // absolutely targets the "detail" view in parent "contacts" state
        "@contacts" : {}       // absolutely targets the unnamed view in parent "contacts" state
        "status@" : {}         // absolutely targets the "status" view in root unnamed state
        "@" : {}               // absolutely targets the unnamed view in root unnamed state
  });

You can see how this ability to not only set multiple views within the same state but ancestor states could become a veritable playground for developer :).

Clone this wiki locally