1
$stateProvider
  .state('dashboard', {
    url:'/dashboard',
    controller: 'MainCtrl',
    templateUrl: 'views/dashboard/main.html'
  })
  .state('dashboard.exchange',{
    templateUrl:'views/dashboard/exchange.html',
    controller: 'ExchangeCtrl',
    url:'/exchange/{exchangeId:[0-9]}',
  })
  .state('dashboard.exchange.module',{
    templateUrl:'views/dashboard/exchangeModule.html',
    controller: 'ExchangeModuleCtrl',
    url:'/module/{exchangeModuleHostName}',
  })
  • '/dashboard' correctly correctly routes to MainCtrl
  • '/dashboard/exchange/1' correctly routes to ExchangeCtrl
  • '/dashboard/exchange/1/module/ae38596496d3' incorrectly routes to ExchangeCtrl

Why doesn't the third url route to ExchangeModuleCtrl? How do I fix this?

Radim Köhler
  • 122,561
  • 47
  • 239
  • 335
Mike B
  • 85
  • 2
  • 6

1 Answers1

1

In case, that we want last child state: 'dashboard.exchange.module' to totally replace the content of its parent 'dashboard.exchange', we have to options:

First option, whole parent is a target

We can place ui-view="" into the parent root <element>. There is a working example. And this would be the 'dashboard.exchange' state template views/dashboard/exchange.html:

<div ui-view="">
  <h3>dashboard.exchange</h3>  
  <br />  
  context just for the state: <b>dashboard.exchange</b>  
</div>

The most important is the root <div ui-view="">, because child will totally replace parent.

Second approach, target grand parent

In this case, we will skip parent. We will directly target grand parent 'dashboard'. There is a working plunker. Here we use absolute naming to target grand parent unnamed view:

.state('dashboard.exchange.module',{
    views : {
      '@dashboard' : {
        templateUrl:'views/dashboard/exchangeModule.html',
        controller: 'ExchangeModuleCtrl',
      },
    },
    url:'/module/{exchangeModuleHostName}',
})

Check these similar Q & A for more details about absolute naming:

Original part of the answer

If we want to follow standard approach - There is a working example

Your code should be workig as is.

The most important is, that each parent must contain target for a child: ui-view="", e.g.:

<div ui-view=""></div>

The view views/dashboard/main.html must contain a target for child state 'dashboard.exchange'

<div >
  <h2>dashboard</h2>      
  <br />      
  <div ui-view=""></div> // this is for child exchange      
</div>

The view views/dashboard/exchange.html must contain a target for child state 'dashboard.exchange.module'

<div >
  <h3>dashboard.exchange</h3>      
  <br />      
  <div ui-view=""></div> // this is for child module      
 </div>

Check it here

Community
  • 1
  • 1
Radim Köhler
  • 122,561
  • 47
  • 239
  • 335
  • Ok, so I may be incorrectly using the "child" concept. While I do want the URL's to be a hierarchy, the dashboard.exchange.module is going to be a completely different view, not an extension of the dashboard.exchange view. dashboard.exchange lists all the modules in the exchange in a grid, and when you click one, the idea was it would show all the details on the module you selected, but not the details on the exchange or the list of modules. – Mike B May 06 '15 at 17:35
  • I updated my answer. Now you have 3 scenarios. They should cover all your needs and show how to use UI-Router. It is up to you which you will choose. But my original answer, with view inheritance would bring more.. $scope inheritance. Maybe check this for more details: http://stackoverflow.com/q/27586546/1679310 – Radim Köhler May 06 '15 at 17:45
  • Thanks! The "skip parent" option 2 does what I am looking for. – Mike B May 06 '15 at 19:28