0

I'm having trouble with a simple ui-router sample I have set up. I have a company page, whose default sub-state should show CompanyProfile, but it defaults to nothing until I click profile. Once I clicked employees, I have to click profile twice to get it to show again. Ideally I want ui-sref="company()" and ui-sref="company.profile()" to display the same screens. It seems like I'm missing something small..

Here's the plnkr:

http://plnkr.co/edit/A3LHGqQIuRlK1QdjuzrP?p=preview

HTML:

  <a ui-sref="company()">company</a>
  | <a ui-sref="company.profile()">profile</a>
  | <a ui-sref="company.employees()">employees</a>

JS:

$stateProvider
    .state('company', {
        url: '/',
        templateUrl: 'company.html',
        controller: 'CompanyCtrl as CompanyCtrl'
    })
    .state('company.profile', {
        url: '',
        templateUrl: 'profile.html',
        controller: 'CompanyProfileCtrl as CompanyProfileCtrl'
    })
    .state('company.employees', {
        url: '/employees',
        templateUrl: 'employees.html',
        controller: 'CompanyEmployeesCtrl as CompanyEmployeesCtrl'
    });

btw, I'm writing everything as components and decided to define the routes in each component, so you'll find the 3 state definitions in the 3 controllers. I'm not entirely sure this is the best approach or not yet.

1 Answer 1

3

The default state is entirely dependent on how you call $urlRouterProvider.otherwise(), passing it a url transitions the application to the particular url, wherein ui-router detects and looks for the very first state it sees.

In your main.js configuration, defines the / url as the default url for the application, which is technically the company state's url and is the very first state in the chain of parent states and children states, making it the default state. This in fact, is also the resulting url for the company.profile state that you wanted your application to default to.

To solve this problem, depends on the use cases for your application.

  1. Use case: If your application defines the company state as a non-navigational state, then setting it to an abstract state solves the problem.

DEMO

CompanyCtrl.js

$stateProvider
    .state('company', {
        abstract: true,
        url: '/',
        templateUrl: 'company.html',
        controller: 'CompanyCtrl as CompanyCtrl'
    });
  1. Use case: If the company state is nagivational, then simply remove the url definition in the company state and change the url defintion for the company.profile state to '/'. The only caveat for this solution would be the loss of the href attribute to be applied for for any anchor tags defined with the ui-sref="company" state which also implies the application of the text cursor. To mitigate this problem you might as well define all anchor tags with ui-sref attribute with a pointer cursor.

DEMO

CompanyCtrl.js

$stateProvider
    .state('company', {
        templateUrl: 'company.html',
        controller: 'CompanyCtrl as CompanyCtrl'
    });

CompanyProfileCtrl.js

$stateProvider
    .state('company.profile', {
        url: '/',
        templateUrl: 'profile.html',
        controller: 'CompanyProfileCtrl as CompanyProfileCtrl'
    })

style.css

a[ui-sref] {
  cursor: pointer;
}

UPDATE:

  1. Use Case: The same with use case #2 but making the company state an abstract state.

DEMO

CompanyCtrl.js

$stateProvider
    .state('company', {
        abstract: true,
        templateUrl: 'company.html',
        controller: 'CompanyCtrl as CompanyCtrl'
    });
Sign up to request clarification or add additional context in comments.

2 Comments

Hmm, I was aware of the abstract concept, but ui-sref="company" fails navigation to an abstract route. Removing the url from company fixes the defaulting issue, but still has the same navigation issue where I don't necessarily want anyone to navigate to company() without the profile being shown. There is a concept of "Multiple Named Views", but I couldn't figure out how to fit this into my goal. Are you intimately familiar with how they work? github.com/angular-ui/ui-router/wiki/Multiple-Named-Views
Yes I am very familiar with multiple named views, but I don't think it is necessary for your case. Please check my update, use case #3.

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.