I have a abstract profile
state, which has multiple child states (for different tabs of the profile page), and then I want to have another child state of profile be a modal. I've implemented it something like this:
$stateProvider
.state('profile', {
url: '/profile/:profileID',
templateUrl: 'profile.html',
controller: 'ProfileCtrl',
abstract:true,
resolve: {
user: ...
}
})
.state('profile.circles', {
url: '',
templateUrl: 'profilecircles.html',
controller: 'profilecirclesCtrl',
resolve: { circle: ... }
})
.state('profile.squares', {
url: '/collections',
templateUrl: 'profilesquares.html',
controller: 'profilesquaresCtrl',
resolve: { squares: ... }
})
.state('profile.editprofile', {
url: '/edit',
onEnter: ['$window','$modal', function($window, $modal) {
$modal.open({
templateUrl: 'editprofile.html',
controller: 'editProfileCtrl',
resolve: {
user: ...
}
}).result.then(function() {
$window.history.back();
},function() {
$window.history.back();
});
}]
})
This works great, except for the fact that because editprofile is a sibling of squares and circles, when that state is active and the modal is in view, the squares or circle state is unloaded, and loaded back in again when the modal is closed.
Is there any way to have those states remain active when the profile.editprofile state is active? I'm after something like state..editprofile
.
As there is currently no ideal solution, I have come up with a reasonably elegant solution. My code is generalized, easy to understand and commented so that it should be easy to adapt to any project.
See the comments in the code for the most significant points.
$stateProvider
// modal will open over this state from any substate
.state('foo', {
abstract: true,
url: '/:fooProp',
templateUrl: 'foo.html',
controller: 'FooController'
})
.state('foo.main', {
url: '',
templateUrl: 'foo-main.html',
controller: 'FooMainController'
})
.state('foo.bar', {
url: '/bars/:barId',
templateUrl: 'foo-bar.html',
controller: 'FooBarController'
})
// append /modal route to each `foo` substate
.state('foo.main.modal', getModalState())
.state('foo.bar.modal', getModalState())
;
function getModalState() {
return {
url: '/modal',
onEnter: [
'$modal',
'$state',
function($modal, $state) {
$modal.open({
templateUrl: 'foo-modal.html',
controller: 'FooModalController'
}).result.finally(function() {
// go to parent state - the current `foo` substate
$state.go('^');
});
}
]
}
}
$scope.goToModalState = function() {
// go to this state's `modal` state
$state.go($state.current.name+'.modal');
};
<a ng-click="goToModalState()">Open Modal</a>
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