Reputation: 83
Having trouble managing my parent-child state mostly as I am new to ui-router. However, I've done research and came across solutions that require hard-coding of routes but are not dynamic.
What I currently have:
<div> <!-- parent state -->
<div ng-if="'.' | isState">
<!--
background hierarchy that should be visible only when
parent state is active and not a child state of the parent
-->
</div>
<nav>
<a ui-sref="." ui-sref-active="active">Parent</a>
<a ui-sref=".child1" ui-sref-active="active">Child 1</a>
<a ui-sref=".child2" ui-sref-active="active">Child 2</a>
</nav>
<div ui-view></div>
</div>
What I'm trying to accomplish?
When the parent loads, I want the background to show something. It takes up the whole screen. The ui-view
will not take up the whole screen. As such, I want background element to be hidden or removed when route does not exactly match the parent's state (if parent's route is /root/parent
, I want background to be visible only when state is exactly /root/parent
and not /root/parent/child1
).
I am able to achieve what I want only when I provide the exact expected route. For example ng-if="'root.parent' | isState"
.
Also, ui-sref-active="active"
retains active
class when children views are shown (it is expected but I want the class only to be active when the route matches exactly).
However, I do not feel that it is good to hard-code route of the parent into view. I just want it to match whatever route it belongs to. As such, if I later decide to move it to /root/parent/car
, I shouldn't have to update ng-if
and ui-sref-active
to reflect the change.
Has anyone ran into the issue and was able to resolve it?
Upvotes: 3
Views: 4016
Reputation: 1436
The simplest solution is checking the state in the controller and do what you need to do
app.controller('appCtrl', function($scope, $state) {
if ($state.is('my-active-state')) {
// do stuff when the state is active
} else {
// do stuff when the state is NOT active
}
});
Check the Docs for more info.
Upvotes: 0
Reputation: 83
Thanks for the replies but one of the conditions in a solution I was seeking was to try and avoid hard-coding a state. My solution is as follows:
For the nav links, I had to read the ui-router directive code to find ui-sref-active-eq
directive, which I applied in the following way:
<nav>
<a ui-sref="." ui-sref-active-eq="active">Parent</a>
<a ui-sref=".child1" ui-sref-active="active">Child 1</a>
<a ui-sref=".child2" ui-sref-active="active">Child 2</a>
</nav>
The directive ensure that Parent
link is active only when the URL is exactly equal to the parent's URL.
As for the showing/hiding the background, I have the following code. Again, note that in neither case do I hard-code a state name:
function ParentController ($scope, $state, $stateParams, $q) {
var model = this;
var controllerState = $state.current.name;
$scope.showBackground = true;
$scope.$on('$stateChangeSuccess', onStateChange);
init();
function init () {
onStateChange();
}
function onStateChange() {
$scope.showBackground = $state.is(controllerState);
}
}
And then in the View:
<div ng-if="showBackground">
<!--
background hierarchy that should be visible only when
parent state is active and not a child state of the parent
-->
</div>
Upvotes: 1
Reputation: 18647
This can be accomplished in few ways, as you might have a parentController
separate.
You can check the state in controller and prevent it in view using ng-if
Controller:
app.controller('myCtrl', function($scope,$state) {
if($state.current.name == 'your parentstate')
{
$scope.stateName = true;
}
else
{
$scope.stateName = false;
}
});
View:
<div ng-if="stateName">
// this only executes if current stateName is parent state
</div>
The above only executes if current stateName is parent state
Or,
You can simply remove active class
from child routes,
<a ui-sref=".child1">Child 1</a>
<a ui-sref=".child2">Child 2</a>
Now, add CSS to active class so that it only appears in background for parent.
Upvotes: 0
Reputation: 2878
Use $state.current.name
for your condition
<div ng-if="$state.current.name === 'state1'">
</div>
Upvotes: 3