0

I would like to have a common state with all the common views like the header and the sidebar, and a template where I would like to load different views that can change when the state is changing.

I have an index HTML file like this:

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

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

    <div class="container">
        <div class="wrapper">
            <div ui-view="content"></div>
        </div>
    </div>
...

While the AngularJS config is something like this:

$stateProvider
    .state('mainCommonState', {
        url: '',
        abstract: true,
        views: {
            header: {
                templateUrl: 'app/common/header.html',
                controller: 'headerCtrl',
                controllerAs: 'vm'
            },
            sidebar: {
                templateUrl: 'app/common/sidebar.html',
                controller: 'sidebarCtrl',
                controllerAs: 'vm'
            },
            content: {}
        },
        resolve: {
            apiEnvironment: function ($q, environmentApiService) {
                var deferred = $q.defer();
                deferred.resolve(environmentApiService.getApiEnvironment());
                return deferred.promise;
            }
        }
    })
    .state('first-page-content', {
        url: '/first-page-content',
        parent: 'mainCommonState',
        views: {
            content: {
                templateUrl: 'app/components/first-page-content.html'
                controller: 'firstPageCtrl',
                controllerAs: 'vm'
            }
        }
    })
    .state('second-page-content', {
        url: '/second-page-content',
        parent: 'mainCommonState',
        views: {
            content: {
                templateUrl: 'app/components/second-page-content.html'
                controller: 'secondPageCtrl',
                controllerAs: 'vm'
            }
        }
    })
    .state('third-page-content', {
        url: '/third-page-content',
        parent: 'mainCommonState',
        views: {
            content: {
                templateUrl: 'app/components/third-page-content.html'
                controller: 'thirdPageCtrl',
                controllerAs: 'vm'
            }
        }
    })

For some reason this is not working: I have an empty view instead of the 3 templates that I would like to show in the content ui-view.

If I define a template (even a blank template) inside the the abstract state, the view that is always showing is the one inside the abstract state mainCommonState.

Where am I wrong?


1st Edit: UPDATE Following the first answer

Following the suggestion from Chris T, I have updated my code, but there still something missing.

I have created a Plunker so you can help me fixing the issues.


2nd Edit

Following the suggestions from Chris T, I have updated the code using the absolute path for the content view and now the contents are switching correctly.

I have updated the Plunker accordingly to that and introduced a new level of nesting view (tabs in the first page), and I would like to have the first tab active when the first page content is loaded.

If I follow these solutions and set empty the url of the first page and set it to the first tab instead, this is not working.

Any suggestions?

1 Answer 1

1

Your views are targeting the wrong named ui-view.

.state('second-page-content', {
     url: '/second-page-content',
     parent: 'mainCommonState',
     views: {
         content: {
             templateUrl: 'app/components/second-page-content.html'
             controller: 'secondPageCtrl',
             controllerAs: 'vm'
         }
     }
 })

In this snippet, it targets the ui-view named content from the parent state which is mainCommonState. However, the content ui-view was not created in the mainCommonState. It was created in the root template.

Change your view declarations to target the view at the correct state, for example this targets the content view at the root state (which is named empty string):

.state('second-page-content', {
     url: '/second-page-content',
     parent: 'mainCommonState',
     views: {
         'content@': {
             templateUrl: 'app/components/second-page-content.html'
             controller: 'secondPageCtrl',
             controllerAs: 'vm'
         }
     }
 })

In ui-router 1.0 and higher you can also use absolute ui-view names by prefixing with an exclamation

.state('second-page-content', {
     url: '/second-page-content',
     parent: 'mainCommonState',
     views: {
         '!content': {
             templateUrl: 'app/components/second-page-content.html'
             controller: 'secondPageCtrl',
             controllerAs: 'vm'
         }
     }
 })

Read more about view targeting in the UI-Router views guide:

https://ui-router.github.io/guide/views#view-name-only

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

3 Comments

Thanks for the answer, btw I am not getting what I want: if I define an empty view named content in the mainCommonState, and then define it inside the child states (using content@mainCommonState), it is not working... Can you please see the plunker that I have created? plnkr.co/edit/oTQzGVpvsjKiM22NGo5v?p=preview
plnkr.co/edit/GCKGErz68iuEir6Vo7sl?p=preview . you need to target the ui-view tag. the <div ui-view="content"></div> tag was created in the root template, not in any state. Target it using content@ or !content as shown in the examples
Thanks again for the answer, in the end I preferred to use the absolute path (!content) because it makes more sense to me. Now the second level nested view is not automatically set as default even if the url is defined in the first tab instead of the first page (like suggested here stackoverflow.com/questions/17001589/…). The updated plunker is here plnkr.co/edit/oTQzGVpvsjKiM22NGo5v?p=preview , have you got an idea on how to solve this?

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.