可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
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".
回答1:
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
回答2:
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>
回答3:
Angular UI router now supports this natively. See commit https://github.com/angular-ui/ui-router/commit/bf163ad6ce176ce28792696c8302d7cdf5c05a01
回答4:
My solution was to set:
<li ng-class="{ 'active': state.current.name.indexOf('route1') != -1 }">
The state was already previously added to the controller's scope:
$scope.state = $state;
回答5:
You do not need to do any thing in the controllers. Here is my example code:
<ul class="nav nav-pills nav-stacked" role="tablist">
<li ui-sref-active="active"><a ui-sref="Booking.Step1" href="#/Booking/Step1">Step1</a></li>
<li ui-sref-active="active"><a ui-sref="Booking.Step2" href="#/Booking/Step2" >Step2</a></li>
<li ui-sref-active="active"><a ui-sref="Booking.Step3" href="#/Booking/Step3">Step3</a></li>
<li ui-sref-active="active"><a ui-sref="Booking.Step4" href="#/Booking/Step4">Step4</a></li>
<li ui-sref-active="active"><a ui-sref="Booking.Step5" href="#/Booking/Step5">Step5</a></li>
</ul>
In route configuration:
$stateProvider.state('Booking', {
abstract: true,
url: '/Booking',
templateUrl: "TourApp/Templates/Booking/SideMenu.html",
controller: "SideMenuController"
});
$stateProvider.state('Booking.Step1', {
url: "/Step1",
views: {
'content': {
templateUrl: "TourApp/Templates/Booking/Step1.html",
controller: "Step1Controller"
}
}
});
$stateProvider.state('Booking.Step2', {
url: "/Step2",
views: {
'content': {
templateUrl: "TourApp/Templates/Booking/Step2.html",
controller: "Step2Controller"
}
}
});
回答6:
Now they have updated and the new way to do that is
<a ui-sref-active="{'active': 'main.app.manage.**'}" ui-sref="main.app.manage.people.list"></a>
Below is the state file
angular.module('manage.people', ['people.invite'])
.config(['$stateProvider', function($stateProvider) {
$stateProvider
.state('main.app.manage.people', {
url: '/people',
abstract: true,
cache: false,
views: {
'tabContent': {
template: '<div ui-view="peopleContent"></div>',
controller: 'peopleController'
}
}
})
.state('main.app.manage.people.list', {
url: '/list',
views: {
'peopleContent': {
templateUrl: '/internal/main/app/manage/people/views/people.html',
controller: 'peopleListController'
}
}
});
回答7:
We already have a solution without any "hack" HERE
That's the way to do:
HTML >
<li ui-sref-active="active" >
<a href="#" class="submenu" ui-sref="bands">
<i class="fa fa-location-arrow" aria-hidden="true"></i>
Bands
<span class="fa fa-chevron-down"></span>
</a>
<ul class="nav child_menu">
<li ui-sref-active="active">
<a ui-sref="bands.nirvana">
Nirvana
</a>
</li>
<li ui-sref-active="active">
<a ui-sref="bands.iron">
Iron
</a>
</li>
<li ui-sref-active="active">
<a ui-sref="bands.metalica">
Metalica
</a>
</li>
</ul>
Our router config will be like this >
$stateProvider.state('bands', {
abstract: true,
url: '/bands',
templateUrl: "myapp/categories/template.bands.html", //<ui-view></ui-view>
controller: "SomeController as vm"
}).state('bands.nirvana', {
url: '/nirvana',
templateUrl: "myapp/categories/band.nirvana.html",
controller: "SomeController as vm"
}).state('bands.iron', {
url: '/iron',
templateUrl: "myapp/categories/band.iron.html",
controller: "SomeController as vm"
}).state('bands.meatlica', {
url: '/metalica',
templateUrl: "myapp/categories/band.metalica.html",
controller: "SomeController as vm"
})
回答8:
I have come here 2 years later the question was asked but angular-ui-router
has much proficient approach in solving this issue. It worked for nested states too.
<ul>
<li ui-sref-active="active" class="item">
<a ui-sref="home">Home</a>
</li>
<!-- ... -->
</ul>
When app navigates to home
state, this is how resulting HTML will appear :
<ul>
<li ui-sref-active="active" class="item active">
<a ui-sref="home">Home</a>
</li>
<!-- ... -->
</ul>
ui-sref-active quick reference :
A directive working alongside ui-sref to add classes to an element
when the related ui-sref directive's state is active, and removing
them when it is inactive. The primary use-case is to simplify the
special appearance of navigation menus relying on ui-sref, by having
the "active" state's menu button appear different, distinguishing it
from the inactive menu items.
Complete documentation.
回答9:
I hope this is what you have been looking for.Place the parent url in the list class ,now whenever you navigate to child class parent class will be active
Step 1: Add a Controller for your nav bar orin your existing controller where nav bar is included add the following
app.controller('navCtrl', ['$scope', '$location', function($scope, $location) {
$scope.isActive = function(destination) {
return destination === $location.path();
}
}]);
Step2: In your nav bar
<li ng-class="{active: isActive('/home')}"><a ui-sref="app.home">Browse Journal</a></li>
Thats it.