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?

1 Answer 1

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

Sign up to request clarification or add additional context in comments.

3 Comments

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.
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: stackoverflow.com/q/27586546/1679310
Thanks! The "skip parent" option 2 does what I am looking for.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.