2

I'm using UI-router's $stateProvider for the routing on an angularjs project and find myself repeating a lot of the same configuration for the route views.

For example:

$stateProvider.state('triage', {
    url:       '/operations/triage',
    views: {
        "header": {
            controller:  'CommonCtrl',
            templateUrl: 'common/header.tpl.html'
        },
        "submenu": {
            controller:  'CommonCtrl',
            templateUrl: 'common/submenu.tpl.html'

        },
        "content": {
            controller: 'TriageCtrl',
            templateUrl: 'operations/triage/triage.tpl.html'
        },
        "footer": {
            templateUrl: 'common/footer.tpl.html'
        }
    },

The header, submenu and footer will be the same for almost every state, the content is really the only part that is variable.

Is there a way to configure the router to always use predefined controllers and templates unless otherwise specified.

Radim Köhler
  • 122,561
  • 47
  • 239
  • 335
Parris Varney
  • 11,320
  • 12
  • 47
  • 76

1 Answers1

1

Solution here could be called: layout root state. As in detail described here:

One of the plunkers

we can create a super parent state 'index' or 'root' (there could be few of them for different state families, e.g. standard, login, doc) which is creating unnamed target for its child/ren (ui-view="") while injecting related templates around:

.state('index', {
    abstract: true,
    //url: '/',
    views: {
      '@' : {
        templateUrl: 'layout.html',
        controller: 'IndexCtrl'
      },
      'top@index' : { templateUrl: 'tpl.top.html',},
      'left@index' : { templateUrl: 'tpl.left.html',},
      // this one is unnamed - a target for children
      '@index' : { templateUrl: 'tpl.main.html',},
    },
  })

So, in this example the layout.html would look like:

<div>

  <section class="left">
      <div ui-view="left"></div>
    </section>

  <section class="right">

    <section class="top">
      <div ui-view="top"></div>
    </section>  

    <section class="main">
      // here is the unnamed view - filled by this state
      // but later target for the child states
      <div ui-view=""></div>
    </section>

  </section>
</div>

Now, we can inject that root state into any existing state:

.state('client', {
    parent: 'index',
    ...
  })
.state('product', {
    parent: 'index',
    ...
  })

so they will have unchanged name ('client', 'product'), i.e. without prefix 'index' or 'root' but will be injected into existing template

The example

Community
  • 1
  • 1
Radim Köhler
  • 122,561
  • 47
  • 239
  • 335
  • 1
    Thank you for taking the time to write our that answer. Your answer is easier to understand than the accepted answers you linked to. – Parris Varney Aug 11 '15 at 19:20