balteo
balteo

Reputation: 24659

Issue with the Angular UI router when inheriting from a parent state

I have an issue with my Angular UI router configuration.

I have an abstract authenticated state that all of my authenticated pages inherit from. Furthermore, I have a dashboard state that tries to inherit from this authenticated state using the parent: 'authenticated' notation.

Here is my configuration:

   .state('authenticated', {
        abstract: true,
        resolve: {
            currentMember: ['$rootScope', '$q', function ($rootScope, $q) {
                return $rootScope.authenticated || $q.reject({unAuthorized: true});
            }]
        }
    })
    .state('dashboard', {
        url: '/dashboard',
        controller: 'DashboardCtrl',
        templateUrl: 'dashboard/views/dashboard.view.html',
        parent: 'authenticated'
    })

However, using the above configuration, my dashboard page is always empty...

If I comment out the parent property as follows:

//parent: 'authenticated'

..then the dashboard view is populated with its contents properly...

Can anyone please help?

Upvotes: 1

Views: 69

Answers (1)

Radim Köhler
Radim Köhler

Reputation: 123861

What we need here is a target for our child view, we need a setting: template: "<ui-view />" in the parent state definition:

.state('authenticated', {
    abstract: true,
    template: "<ui-view />", // here
    resolve: {
        currentMember: ['$rootScope', '$q', function ($rootScope, $q) {
            return $rootScope.authenticated || $q.reject({unAuthorized: true});
        }]
    }
})

This template: "<ui-view />", piece of code is now doing essential part of our state machine: it creates target for our child .state('dashboard'.... That state will now be placed (its unnamed view) into that parent target.

The reason why it was working, when we commented out the parent: setting was:

our view of the state 'dashboard' was injected into index.html target <div ui-view=""> - (index.html is so called root state).

The templatce could also be like '<div ui-view=""></div>'. I just used simplified expression resulting in the same behaviour...

To get more ideas about that all, please, check:

View Names - Relative vs. Absolute Names

Behind the scenes, 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. You can also choose to write your view names in the absolute syntax.

...

code snippet cite:

.state('contacts.detail', {
  views: {
    ////////////////////////////////////
    // Relative Targeting             //
    // Targets parent state ui-view's //
    ////////////////////////////////////

    // Relatively targets the 'detail' view in this state's parent state, 'contacts'.
    // <div ui-view='detail'/> within contacts.html
    "detail" : { },            

    // Relatively targets the unnamed view in this state's parent state, 'contacts'.
    // <div ui-view/> within contacts.html
    "" : { }, 

    ///////////////////////////////////////////////////////
    // Absolute Targeting using '@'                      //
    // Targets any view within this state or an ancestor //
    ///////////////////////////////////////////////////////

    // Absolutely targets the 'info' view in this state, 'contacts.detail'.
    // <div ui-view='info'/> within contacts.detail.html
    "[email protected]" : { }

    // Absolutely targets the 'detail' view in the 'contacts' state.
    // <div ui-view='detail'/> within contacts.html
    "detail@contacts" : { }

    // Absolutely targets the unnamed view in parent 'contacts' state.
    // <div ui-view/> within contacts.html
    "@contacts" : { }

Upvotes: 1

Related Questions