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.
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.
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?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With