Reputation: 1071
This question is based on "How can I persist sibling ui-views when changing state" (plunker).
I try to keep a view (content) unchanged, when I change the state in the main navigation (mainNav).
The content should only be set by the sub navigation, and remain when changing the main navigation.
Is there a possibility to remain a view in ui-router, even if the state is left?
angular.module('MyApp', [
'ui.router'
])
.config(function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/');
$stateProvider
.state('index', {
url: '/',
views: {
'@': {
templateUrl: 'layout.html'
},
'mainNav@index': {
template: '<a ui-sref="Main3">Main3 - with sub</a><br />'
+ '<a ui-sref="Main4">Main4 - with sub</a>'
},
'subNav@index' : {
template: '<p>This is the sub navigation</p>'
},
'content@index': {
template: '<p>Content shared for MAINs</p>'
}
}
})
.state('Main3', {
parent: 'index',
url: '/Main3',
views: {
/*'mainNav': {
},*/
'subNav': {
template: '<a ui-sref="Main3.Sub1">Main3.Sub1</a><br />'
+ '<a ui-sref="Main3.Sub2">Main3.Sub2</a>'
}
}
})
.state('Main4', {
parent: 'index',
url: '/Main4',
views: {
'subNav': {
template: '<a ui-sref="Main4.Sub1">Main4.Sub1</a><br />'
+ '<a ui-sref="Main4.Sub2">Main4.Sub2</a>'
}
}
})
.state('Main3.Sub1', {
url: '/Sub1',
views: { 'content@index': { template: 'Content of Main3.Sub1' } }
})
.state('Main3.Sub2', {
url: '/Sub2',
views: { 'content@index': { template: 'Content of Main3.Sub2' } }
})
.state('Main4.Sub1', {
url: '/Sub1',
views: { 'content@index': { template: 'Content of Main4.Sub1' } }
})
.state('Main4.Sub2', {
url: '/Sub2',
views: { 'content@index': { template: 'Content of Main4.Sub2' } }
})
});
I found Persist state when changing to another state, but it doesn't solve the problem completely. The state is persistent, but there is no consideration of remaining a view consistent when navigating to a different state.
Upvotes: 8
Views: 654
Reputation: 105
Walfrat's answer seems correct. I'm just trying to elaborate, and maybe understand what you're looking for. Here's what I think you're asking for:
// app.js
...
$stateProvider
.state('nav', {
url: '/',
templateUrl: 'app/templates/nav.html',
controller: 'NavCtrl as nav',
abstract: true
})
.state('nav.subNav', {
url: 'subNav/',
templateUrl: 'app/templates/subNav.html',
controller: 'subNavCtrl as subNav',
abstract: true
})
.state('nav.subNav.index', {
url: 'index',
templateUrl: 'app/templates/index.html',
controller: 'IndexCtrl as index'
});
$urlRouterProvider.otherwise('/subNav/index');
...
In this example, you can set the default view by including abstract: true
in the nav state (note: I've never tried it three states deep, but it works with two states). This may give you the effect you are looking for.
As for having sub-navigations as views, it's should be possible, but I'm not sure if it's recommended to have deep nested views like that. Is this close to what you're looking for?
Upvotes: 1
Reputation: 5353
Yes it is and it's quite easy however it has its limitation : store the data you need in the parent's scope.
$state.state('parent', {
controller:'ParentController'
});
$state.state('parent.child1', {
controller:'ChildController'
});
$state.state('parent.child2', {
controller:'ChildController2'
});
// in Parent controller
$scope.context = {};// it important to create a intermediary field that will store the data, otherwise you might have a problem with scopes inheritance
// in Child controller
$scope.context.toto = 'titi';
// in other child controller $scope.context.toto = 'woof';
Note : i don' know if this will work if you use controllerAs syntax.
I personnally use it for a multi page form with next/back buttons in it.
Upvotes: 1