Reputation: 1436
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?
Upvotes: 0
Views: 333
Reputation: 8216
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'
}
}
})
https://ui-router.github.io/guide/views#view-name-only
Upvotes: 1