Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular UI Router: How do I get parent view to be "active" when navigating to nested view?

I'm working on a project that has implemented the UI router and it's using ui-sref-active="active" to add the active class to the navigation menu item when that item is the current route. However, when you navigate to a nested view within that view, the parent menu item is no longer active. See the following Plunker:

http://plnkr.co/edit/2CoEdS?p=preview

By default (or if you click on it) Route 1 is "active". When you click on "Show List," you will see that Route 1 is no longer active.

Edit:

The only difference between this example and my actual project is that the navigation menu in my actual project has its own controller and so does not use the same scope as the controller for "route1".

like image 429
Ian Walter Avatar asked Feb 26 '14 22:02

Ian Walter


3 Answers

EDIT For updated ui-router 0.2.13:

ui-sref-active="active" now sets the 'active' class when the current state is the ui-sref's state or any child

ui-sref-active-eq="active" behaves as the previous iterations of ui-sref-active, and only sets the class for the exact state

Original Answer:

See open ui-router issues: https://github.com/angular-ui/ui-router/issues/704 and 818

A general workaround people are suggesting is:

ng-class="{active:$state.includes('route1')}"

Of course, $state must be added to $scope. See updated plunk: http://plnkr.co/edit/KHLDJP?p=preview

like image 74
Chris T Avatar answered Sep 27 '22 22:09

Chris T


You are having a wrong understanding of ui-sref-active="active"

<li ui-sref-active="active"><a ui-sref="route1">Route 1</a></li>

This will show special css highlighting only when you are in state route1 (reference https://github.com/angular-ui/ui-router/wiki/Quick-Reference#wiki-ui-sref-active). This is the case when you click on route 1. But when you click on "Show list" you are no longer in route1. Rather you are in state "route1.list" . You can verify this by writing the following code. This is strictly for understanding how state works.

js

inside controller

$rootScope.currentState = $state.$current.name //using rootScope so that you can access the variable anywhere inside html

inside html

{{currentState}}

If you look closely at documentation of ui-sref-active, it not only looks at stateName but also stateParams, hence when you go to substate it no longer changes css. From the sourcecode it becomes clearer.

 function update() {
        if ($state.$current.self === state && matchesParams()) {
          $element.addClass(activeClass);
        } else {
          $element.removeClass(activeClass);
        }// route1===route1.list will not be true.

to solve the problem, remember scope variables are inherited in nested views.

inside controller of route.

$scope.route1Active = true;

in html

<li ng-class={active:route1Active}><a ui-sref="route1">Route 1</a></li>
like image 32
himangshuj Avatar answered Sep 27 '22 21:09

himangshuj


Angular UI router now supports this natively. See commit https://github.com/angular-ui/ui-router/commit/bf163ad6ce176ce28792696c8302d7cdf5c05a01

like image 21
Kenneth Lynne Avatar answered Sep 27 '22 21:09

Kenneth Lynne