如何突出显示当前菜单项?

AngularJS是否帮助在当前页面的链接上设置active类?

我想一定有什么神奇的方法可以做到,但我似乎找不到。

我的菜单是这样的:

 <ul>
<li><a class="active" href="/tasks">Tasks</a>
<li><a href="/actions">Tasks</a>
</ul>

并且我在我的路由中为他们每个人都有控制器:TasksControllerActionsController

但我找不到方法将a链接上的“active”类绑定到控制器。

有提示吗?

203932 次浏览

在视图

<a ng-class="getClass('/tasks')" href="/tasks">Tasks</a>

在控制器

$scope.getClass = function (path) {
return ($location.path().substr(0, path.length) === path) ? 'active' : '';
}

这样,tasks链接将在任何以'/tasks'开头的url中具有活动类。/任务/ 1 /报告)

有一个ng-class指令,它绑定变量和css类。 它还接受对象(className vs bool值对)

下面是一个例子,http://plnkr.co/edit/SWZAqj

我建议在链接上使用指令。

但它还不完美。小心哈希邦;)

下面是指令的javascript代码:

angular.module('link', []).
directive('activeLink', ['$location', function (location) {
return {
restrict: 'A',
link: function(scope, element, attrs, controller) {
var clazz = attrs.activeLink;
var path = attrs.href;
path = path.substring(1); //hack because path does not return including hashbang
scope.location = location;
scope.$watch('location.path()', function (newPath) {
if (path === newPath) {
element.addClass(clazz);
} else {
element.removeClass(clazz);
}
});
}
};
}]);

下面是它在html中的用法:

<div ng-app="link">
<a href="#/one" active-link="active">One</a>
<a href="#/two" active-link="active">One</a>
<a href="#" active-link="active">home</a>
</div>

之后用css样式:

.active { color: red; }
@Renan-tomal-fernandes的回答很好,但需要一些改进才能正确工作。 事实上,它总是会在触发时检测到到主页(/)的链接,即使你在另一个部分 所以我稍微改进了一下,这是代码。 我使用引导,因此活动部分在<li>元素中,而不是<a>.

控制器

$scope.getClass = function(path) {
var cur_path = $location.path().substr(0, path.length);
if (cur_path == path) {
if($location.path().substr(0).length > 1 && path.length == 1 )
return "";
else
return "active";
} else {
return "";
}
}

模板

<div class="nav-collapse collapse">
<ul class="nav">
<li ng-class="getClass('/')"><a href="#/">Home</a></li>
<li ng-class="getClass('/contents/')"><a href="#/contests/">Contents</a></li>
<li ng-class="getClass('/data/')"><a href="#/data/">Your data</a></li>
</ul>
</div>

我有类似的问题菜单位于外面控制器范围。不确定这是最好的解决方案还是推荐的解决方案,但这对我来说是有效的。我已经在我的应用程序配置中添加了以下内容:

var app = angular.module('myApp');


app.run(function($rootScope, $location){
$rootScope.menuActive = function(url, exactMatch){
if (exactMatch){
return $location.path() == url;
}
else {
return $location.path().indexOf(url) == 0;
}
}
});

那么在视图中,我有:

<li><a href="/" ng-class="{true: 'active'}[menuActive('/', true)]">Home</a></li>
<li><a href="/register" ng-class="{true: 'active'}[menuActive('/register')]">
<li>...</li>

以下是我在阅读了上面的一些优秀建议后想出的解决方案。在我的特殊情况下,我试图使用引导选项卡组件作为我的菜单,但不想使用Angular-UI版本,因为我想让选项卡作为菜单,其中每个选项卡都是可书签的,而不是作为一个页面的导航。(如果你对Angular-UI版本的bootstrap选项卡感兴趣,请参阅http://angular-ui.github.io/bootstrap/#/tabs)。

我真的很喜欢kfis关于创建你自己的指令来处理这个问题的回答,然而,有一个需要放在每个链接上的指令似乎很麻烦。因此,我创建了自己的Angular指令,它只被放置在ul上。以防其他人也在尝试做同样的事情,我想把它贴在这里,尽管如我所说,上面的许多解决方案也同样有效。就javascript而言,这是一个稍微复杂一些的解决方案,但它用最少的标记创建了一个可重用的组件。

下面是指令的javascript和ng:view的路由提供程序:

var app = angular.module('plunker', ['ui.bootstrap']).
config(['$routeProvider', function($routeProvider) {
$routeProvider.
when('/One', {templateUrl: 'one.html'}).
when('/Two', {templateUrl: 'two.html'}).
when('/Three', {templateUrl: 'three.html'}).
otherwise({redirectTo: '/One'});
}]).
directive('navTabs', ['$location', function(location) {
return {
restrict: 'A',
link: function(scope, element) {
var $ul = $(element);
$ul.addClass("nav nav-tabs");


var $tabs = $ul.children();
var tabMap = {};
$tabs.each(function() {
var $li = $(this);
//Substring 1 to remove the # at the beginning (because location.path() below does not return the #)
tabMap[$li.find('a').attr('href').substring(1)] = $li;
});


scope.location = location;
scope.$watch('location.path()', function(newPath) {
$tabs.removeClass("active");
tabMap[newPath].addClass("active");
});
}


};


}]);

然后在你的html中你只需:

<ul nav-tabs>
<li><a href="#/One">One</a></li>
<li><a href="#/Two">Two</a></li>
<li><a href="#/Three">Three</a></li>
</ul>
<ng:view><!-- Content will appear here --></ng:view>

这是它的活塞:http://plnkr.co/edit/xwGtGqrT7kWoCKnGDHYN?p=preview

使用指令(因为我们在这里做的是DOM操作),下面可能是最接近“angular方式”的方法:

$scope.timeFilters = [
{'value':3600,'label':'1 hour'},
{'value':10800,'label':'3 hours'},
{'value':21600,'label':'6 hours'},
{'value':43200,'label':'12 hours'},
{'value':86400,'label':'24 hours'},
{'value':604800,'label':'1 week'}
]


angular.module('whatever', []).directive('filter',function(){
return{
restrict: 'A',
template: '<li ng-repeat="time in timeFilters" class="filterItem"><a ng-click="changeTimeFilter(time)">\{\{time.label}}</a></li>',
link: function linkFn(scope, lElement, attrs){


var menuContext = attrs.filter;


scope.changeTimeFilter = function(newTime){
scope.selectedtimefilter = newTime;


}


lElement.bind('click', function(cevent){
var currentSelection = angular.element(cevent.srcElement).parent();
var previousSelection = scope[menuContext];


if(previousSelection !== currentSelection){
if(previousSelection){
angular.element(previousSelection).removeClass('active')
}
scope[menuContext] = currentSelection;


scope.$apply(function(){
currentSelection.addClass('active');
})
}
})
}
}
})

然后你的HTML看起来像这样:

<ul class="dropdown-menu" filter="times"></ul>
对我来说最重要的是不要改变bootstrap的默认代码。 这是我的菜单控制器,搜索菜单选项,然后添加我们想要的行为
file: header.js
function HeaderCtrl ($scope, $http, $location) {
$scope.menuLinkList = [];
defineFunctions($scope);
addOnClickEventsToMenuOptions($scope, $location);
}


function defineFunctions ($scope) {
$scope.menuOptionOnClickFunction = function () {
for ( var index in $scope.menuLinkList) {
var link = $scope.menuLinkList[index];
if (this.hash === link.hash) {
link.parentElement.className = 'active';
} else {
link.parentElement.className = '';
}
}
};
}


function addOnClickEventsToMenuOptions ($scope, $location) {
var liList = angular.element.find('li');
for ( var index in liList) {
var liElement = liList[index];
var link = liElement.firstChild;
link.onclick = $scope.menuOptionOnClickFunction;
$scope.menuLinkList.push(link);
var path = link.hash.replace("#", "");
if ($location.path() === path) {
link.parentElement.className = 'active';
}
}
}


<script src="resources/js/app/header.js"></script>
<div class="navbar navbar-fixed-top" ng:controller="HeaderCtrl">
<div class="navbar-inner">
<div class="container-fluid">
<button type="button" class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
<span class="icon-bar"></span> <span class="icon-bar"></span>
<span     class="icon-bar"></span>
</button>
<a class="brand" href="#"> <img src="resources/img/fom-logo.png"
style="width: 80px; height: auto;">
</a>
<div class="nav-collapse collapse">
<ul class="nav">
<li><a href="#/platforms">PLATFORMS</a></li>
<li><a href="#/functionaltests">FUNCTIONAL TESTS</a></li>
</ul>
</div>
</div>
</div>
</div>

这是一个扩展的kfis指令,我做了允许不同级别的路径匹配。从本质上讲,我发现需要匹配URL路径到一定深度,因为精确匹配不允许嵌套和默认状态重定向。希望这能有所帮助。

    .directive('selectedLink', ['$location', function(location) {
return {
restrict: 'A',
scope:{
selectedLink : '='
},
link: function(scope, element, attrs, controller) {
var level = scope.selectedLink;
var path = attrs.href;
path = path.substring(1); //hack because path does not return including hashbang
scope.location = location;
scope.$watch('location.path()', function(newPath) {
var i=0;
p = path.split('/');
n = newPath.split('/');
for( i ; i < p.length; i++) {
if( p[i] == 'undefined' || n[i] == 'undefined' || (p[i] != n[i]) ) break;
}


if ( (i-1) >= level) {
element.addClass("selected");
}
else {
element.removeClass("selected");
}
});
}


};
}]);

下面是我如何使用这个链接

<nav>
<a href="#/info/project/list"  selected-link="2">Project</a>
<a href="#/info/company/list" selected-link="2">Company</a>
<a href="#/info/person/list"  selected-link="2">Person</a>
</nav>

该指令将匹配在该指令的属性值中指定的深度级别。只是意味着它可以在其他地方多次使用。

在我的例子中,我通过创建一个负责导航的简单控制器来解决这个问题

angular.module('DemoApp')
.controller('NavigationCtrl', ['$scope', '$location', function ($scope, $location) {
$scope.isCurrentPath = function (path) {
return $location.path() == path;
};
}]);

只需像这样在元素中添加ng-class:

<ul class="nav" ng-controller="NavigationCtrl">
<li ng-class="{ active: isCurrentPath('/') }"><a href="#/">Home</a></li>
<li ng-class="{ active: isCurrentPath('/about') }"><a href="#/about">About</a></li>
<li ng-class="{ active: isCurrentPath('/contact') }"><a href="#/contact">Contact</a></li>
</ul>

这里有一个简单的方法,可以很好地使用Angular。

<ul>
<li ng-class="{ active: isActive('/View1') }"><a href="#/View1">View 1</a></li>
<li ng-class="{ active: isActive('/View2') }"><a href="#/View2">View 2</a></li>
<li ng-class="{ active: isActive('/View3') }"><a href="#/View3">View 3</a></li>
</ul>

在你的AngularJS控制器中:

$scope.isActive = function (viewLocation) {
var active = (viewLocation === $location.path());
return active;
};

这个帖子有许多其他类似的答案。

如何用Angular JS设置引导导航栏活动类?< / >

也有同样的问题。下面是我的解决方案:

.directive('whenActive',
[
'$location',
($location)->
scope: true,
link: (scope, element, attr)->
scope.$on '$routeChangeSuccess',
() ->
loc = "#"+$location.path()
href = element.attr('href')
state = href.indexOf(loc)
substate = -1


if href.length > 3
substate = loc.indexOf(href)
if loc.length is 2
state = -1


#console.log "Is Loc: "+loc+" in Href: "+href+" = "+state+" and Substate = "+substate


if state isnt -1 or substate isnt -1
element.addClass 'selected'
element.parent().addClass 'current-menu-item'
else if href is '#' and loc is '#/'
element.addClass 'selected'
element.parent().addClass 'current-menu-item'
else
element.removeClass 'selected'
element.parent().removeClass 'current-menu-item'
])

我是这样做的:

var myApp = angular.module('myApp', ['ngRoute']);


myApp.directive('trackActive', function($location) {
function link(scope, element, attrs){
scope.$watch(function() {
return $location.path();
}, function(){
var links = element.find('a');
links.removeClass('active');
angular.forEach(links, function(value){
var a = angular.element(value);
if (a.attr('href') == '#' + $location.path() ){
a.addClass('active');
}
});
});
}
return {link: link};
});

这可以让你在一个有跟踪活动指令的节中有链接:

<nav track-active>
<a href="#/">Page 1</a>
<a href="#/page2">Page 2</a>
<a href="#/page3">Page 3</a>
</nav>

在我看来,这种方法比其他方法干净得多。

此外,如果你使用的是jQuery,你可以让它更整洁,因为jQlite只有基本的选择器支持。在angular include之前包含jquery的一个更简洁的版本是这样的:

myApp.directive('trackActive', function($location) {
function link(scope, element, attrs){
scope.$watch(function() {
return $location.path();
}, function(){
element.find('a').removeClass('active').find('[href="#'+$location.path()+'"]').addClass('active');
});
}
return {link: link};
});

这是一个jsFiddle

我做了一个纯angular模块(没有jQuery),它也可以处理包含数据的散列url。(例如#/this/is/path?this=is&some=data)

您只需将模块作为依赖项添加,并将auto-active添加到菜单的一个祖先。是这样的:

<ul auto-active>
<li><a href="#/">main</a></li>
<li><a href="#/first">first</a></li>
<li><a href="#/second">second</a></li>
<li><a href="#/third">third</a></li>
</ul>

这个模块是这样的:

(function () {
angular.module('autoActive', [])
.directive('autoActive', ['$location', function ($location) {
return {
restrict: 'A',
scope: false,
link: function (scope, element) {
function setActive() {
var path = $location.path();
if (path) {
angular.forEach(element.find('li'), function (li) {
var anchor = li.querySelector('a');
if (anchor.href.match('#' + path + '(?=\\?|$)')) {
angular.element(li).addClass('active');
} else {
angular.element(li).removeClass('active');
}
});
}
}


setActive();


scope.$on('$locationChangeSuccess', setActive);
}
}
}]);
}());

(当然,你可以只使用指令部分)

同样值得注意的是,这对空哈希值(例如example.com/#或只是example.com)无效,它至少需要有example.com/#/或只是example.com#/。但这是自动发生的ngResource之类的。

这里是小提琴:http://jsfiddle.net/gy2an/8/

对于AngularUI路由器用户:

<a ui-sref-active="active" ui-sref="app">

这将在所选对象上放置一个active类。

这里是另一个突出显示活动链接的指令。

主要特点:

  • 适用于包含动态角度表达式的href
  • 兼容散列导航
  • 与Bootstrap兼容,其中活动类应该应用到父li而不是链接本身
  • 允许使链接活动,如果任何嵌套的路径是活动的
  • 允许禁用make链接,如果它不是活动的

代码:

.directive('activeLink', ['$location',
function($location) {
return {
restrict: 'A',
link: function(scope, elem, attrs) {
var path = attrs.activeLink ? 'activeLink' : 'href';
var target = angular.isDefined(attrs.activeLinkParent) ? elem.parent() : elem;
var disabled = angular.isDefined(attrs.activeLinkDisabled) ? true : false;
var nested = angular.isDefined(attrs.activeLinkNested) ? true : false;


function inPath(needle, haystack) {
var current = (haystack == needle);
if (nested) {
current |= (haystack.indexOf(needle + '/') == 0);
}


return current;
}


function toggleClass(linkPath, locationPath) {
// remove hash prefix and trailing slashes
linkPath = linkPath ? linkPath.replace(/^#!/, '').replace(/\/+$/, '') : '';
locationPath = locationPath.replace(/\/+$/, '');


if (linkPath && inPath(linkPath, locationPath)) {
target.addClass('active');
if (disabled) {
target.removeClass('disabled');
}
} else {
target.removeClass('active');
if (disabled) {
target.addClass('disabled');
}
}
}


// watch if attribute value changes / evaluated
attrs.$observe(path, function(linkPath) {
toggleClass(linkPath, $location.path());
});


// watch if location changes
scope.$watch(
function() {
return $location.path();
},
function(newPath) {
toggleClass(attrs[path], newPath);
}
);
}
};
}
]);

用法:

angular表达式的简单例子,假设是美元的范围。Var = 2,那么如果location是/ url / 2,则链接将是活动的:

<a href="#!/url/\{\{var}}" active-link>

Bootstrap示例,parent li将获得活动类:

<li>
<a href="#!/url" active-link active-link-parent>
</li>

使用嵌套url的示例,如果任何嵌套url是活动的,链接将是活动的(即/ url / 1/ url / 2url / 1/2 /…)

<a href="#!/url" active-link active-link-nested>

复杂示例,链接指向一个url (/ url1),但如果选择了另一个url (/ url2),则将是活动的:

<a href="#!/url1" active-link="#!/url2" active-link-nested>

禁用链接的例子,如果它不是活动的,它将有“禁用”类:

<a href="#!/url" active-link active-link-disabled>

所有活动链接- *属性都可以在任何组合中使用,因此可以实现非常复杂的条件。

如果你想把指令的链接放在一个包装器中,而不是选择每个单独的链接(这样更容易查看Batarang中的作用域),这也很有效:

  angular.module("app").directive("navigation", [
"$location", function($location) {
return {
restrict: 'A',
scope: {},
link: function(scope, element) {
var classSelected, navLinks;


scope.location = $location;


classSelected = 'selected';


navLinks = element.find('a');


scope.$watch('location.path()', function(newPath) {
var el;
el = navLinks.filter('[href="' + newPath + '"]');


navLinks.not(el).closest('li').removeClass(classSelected);
return el.closest('li').addClass(classSelected);
});
}
};
}
]);

加价就是:

    <nav role="navigation" data-navigation>
<ul>
<li><a href="/messages">Messages</a></li>
<li><a href="/help">Help</a></li>
<li><a href="/details">Details</a></li>
</ul>
</nav>

我还应该提到,我在这个例子中使用的是“全脂”jQuery,但你可以很容易地改变我所做的过滤等。

你可以很简单地实现它,这里有一个例子:

<div ng-controller="MenuCtrl">
<ul class="menu">
<li ng-class="menuClass('home')"><a href="#home">Page1</a></li>
<li ng-class="menuClass('about')"><a href="#about">Page2</a></li>
</ul>


</div>

你的控制器应该是这样的:

app.controller("MenuCtrl", function($scope, $location) {
$scope.menuClass = function(page) {
var current = $location.path().substring(1);
return page === current ? "active" : "";
};
});

这是我的意见,这很好。

注意:这与子页不匹配(这是我需要的)。

观点:

<a ng-class="{active: isCurrentLocation('/my-path')}"  href="/my-path" >
Some link
</a>

控制器:

// make sure you inject $location as a dependency


$scope.isCurrentLocation = function(path){
return path === $location.path()
}

我对这个问题的解决方案是在angular模板中使用route.current

当你在菜单中突出显示/tasks路由时,你可以将自己的属性menuItem添加到模块声明的路由中:

$routeProvider.
when('/tasks', {
menuItem: 'TASKS',
templateUrl: 'my-templates/tasks.html',
controller: 'TasksController'
);

然后在你的模板__abc0中,你可以使用以下ng-class指令:

<a href="app.html#/tasks"
ng-class="{active : route.current.menuItem === 'TASKS'}">Tasks</a>

在我看来,这比所有提出的解决方案都要干净得多。

我刚刚写了一个指令。

用法:

<ul class="nav navbar-nav">
<li active><a href="#/link1">Link 1</a></li>
<li active><a href="#/link2">Link 2</a></li>
</ul>

实现:

angular.module('appName')
.directive('active', function ($location, $timeout) {
return {
restrict: 'A',
link: function (scope, element, attrs) {
// Whenever the user navigates to a different page...
scope.$on('$routeChangeSuccess', function () {
// Defer for other directives to load first; this is important
// so that in case other directives are used that this directive
// depends on, such as ng-href, the href is evaluated before
// it's checked here.
$timeout(function () {
// Find link inside li element
var $link = element.children('a').first();


// Get current location
var currentPath = $location.path();


// Get location the link is pointing to
var linkPath = $link.attr('href').split('#').pop();


// If they are the same, it means the user is currently
// on the same page the link would point to, so it should
// be marked as such
if (currentPath === linkPath) {
$(element).addClass('active');
} else {
// If they're not the same, a li element that is currently
// marked as active needs to be "un-marked"
element.removeClass('active');
}
});
});
}
};
});

测试:

'use strict';


describe('Directive: active', function () {


// load the directive's module
beforeEach(module('appName'));


var element,
scope,
location,
compile,
rootScope,
timeout;


beforeEach(inject(function ($rootScope, $location, $compile, $timeout) {
scope = $rootScope.$new();
location = $location;
compile = $compile;
rootScope = $rootScope;
timeout = $timeout;
}));


describe('with an active link', function () {
beforeEach(function () {
// Trigger location change
location.path('/foo');
});


describe('href', function () {
beforeEach(function () {
// Create and compile element with directive; note that the link
// is the same as the current location after the location change.
element = angular.element('<li active><a href="#/foo">Foo</a></li>');
element = compile(element)(scope);


// Broadcast location change; the directive waits for this signal
rootScope.$broadcast('$routeChangeSuccess');


// Flush timeout so we don't have to write asynchronous tests.
// The directive defers any action using a timeout so that other
// directives it might depend on, such as ng-href, are evaluated
// beforehand.
timeout.flush();
});


it('adds the class "active" to the li', function () {
expect(element.hasClass('active')).toBeTruthy();
});
});


describe('ng-href', function () {
beforeEach(function () {
// Create and compile element with directive; note that the link
// is the same as the current location after the location change;
// however this time with an ng-href instead of an href.
element = angular.element('<li active><a ng-href="#/foo">Foo</a></li>');
element = compile(element)(scope);


// Broadcast location change; the directive waits for this signal
rootScope.$broadcast('$routeChangeSuccess');


// Flush timeout so we don't have to write asynchronous tests.
// The directive defers any action using a timeout so that other
// directives it might depend on, such as ng-href, are evaluated
// beforehand.
timeout.flush();
});


it('also works with ng-href', function () {
expect(element.hasClass('active')).toBeTruthy();
});
});
});


describe('with an inactive link', function () {
beforeEach(function () {
// Trigger location change
location.path('/bar');


// Create and compile element with directive; note that the link
// is the NOT same as the current location after the location change.
element = angular.element('<li active><a href="#/foo">Foo</a></li>');
element = compile(element)(scope);


// Broadcast location change; the directive waits for this signal
rootScope.$broadcast('$routeChangeSuccess');


// Flush timeout so we don't have to write asynchronous tests.
// The directive defers any action using a timeout so that other
// directives it might depend on, such as ng-href, are evaluated
// beforehand.
timeout.flush();
});


it('does not add the class "active" to the li', function () {
expect(element.hasClass('active')).not.toBeTruthy();
});
});


describe('with a formerly active link', function () {
beforeEach(function () {
// Trigger location change
location.path('/bar');


// Create and compile element with directive; note that the link
// is the same as the current location after the location change.
// Also not that the li element already has the class "active".
// This is to make sure that a link that is active right now will
// not be active anymore when the user navigates somewhere else.
element = angular.element('<li class="active" active><a href="#/foo">Foo</a></li>');
element = compile(element)(scope);


// Broadcast location change; the directive waits for this signal
rootScope.$broadcast('$routeChangeSuccess');


// Flush timeout so we don't have to write asynchronous tests.
// The directive defers any action using a timeout so that other
// directives it might depend on, such as ng-href, are evaluated
// beforehand.
timeout.flush();
});


it('removes the "active" class from the li', function () {
expect(element.hasClass('active')).not.toBeTruthy();
});
});
});

路线:

$routeProvider.when('/Account/', { templateUrl: '/Home/Account', controller: 'HomeController' });

菜单html:

<li id="liInicio" ng-class="{'active':url=='account'}">

控制器:

angular.module('Home').controller('HomeController', function ($scope, $http, $location) {
$scope.url = $location.url().replace(/\//g, "").toLowerCase();
...

我在这里发现的问题是,菜单项只有在加载整个页面时才处于活动状态。当部分视图被加载时,菜单不会改变。有人知道为什么吗?

根据@kfis的回答,这是评论,我的建议,最终指令如下:

.directive('activeLink', ['$location', function (location) {
return {
restrict: 'A',
link: function(scope, element, attrs, controller) {
var clazz = attrs.activeLink;
var path = attrs.href||attrs.ngHref;
path = path.substring(1); //hack because path does not return including hashbang
scope.location = location;
scope.$watch('window.location.href', function () {
var newPath = (window.location.pathname + window.location.search).substr(1);
if (path === newPath) {
element.addClass(clazz);
} else {
element.removeClass(clazz);
}
});
}
};
}]);

下面是它在html中的用法:

<div ng-app="link">
<a href="#/one" active-link="active">One</a>
<a href="#/two" active-link="active">One</a>
<a href="#" active-link="active">home</a>
</div>

之后用css样式:

.active { color: red; }

对于那些使用ui-router的人,我的答案有点类似于Ender2050,但我更喜欢通过州名测试来做到这一点:

$scope.isActive = function (stateName) {
var active = (stateName === $state.current.name);
return active;
};

相应的HTML:

<ul class="nav nav-sidebar">
<li ng-class="{ active: isActive('app.home') }"><a ui-sref="app.home">Dashboard</a></li>
<li ng-class="{ active: isActive('app.tiles') }"><a ui-sref="app.tiles">Tiles</a></li>
</ul>
使用angular-ui-router的ui-sref-active指令 https://github.com/angular-ui/ui-router/wiki/Quick-Reference#statename < / p >

.
<ul>
<li ui-sref-active="active" class="item">
<a href ui-sref="app.user({user: 'bilbobaggins'})">@bilbobaggins</a>
</li>
<!-- ... -->
</ul>

上面的指令建议对我来说都没用。如果你有一个这样的引导导航栏

<ul class="nav navbar-nav">
<li><a ng-href="#/">Home</a></li>
<li><a ng-href="#/about">About</a></li>
...
</ul>

(可以是$ yo angular启动)然后你想要将.active添加到 <li>元素类列表中,而不是元素本身;即<li class="active">..</li>。所以我写了这个:

.directive('setParentActive', ['$location', function($location) {
return {
restrict: 'A',
link: function(scope, element, attrs, controller) {
var classActive = attrs.setParentActive || 'active',
path = attrs.ngHref.replace('#', '');
scope.location = $location;
scope.$watch('location.path()', function(newPath) {
if (path == newPath) {
element.parent().addClass(classActive);
} else {
element.parent().removeClass(classActive);
}
})
}
}
}])

使用set-parent-active;.active是默认值,所以不需要设置

<li><a ng-href="#/about" set-parent-active>About</a></li>

当链接激活时,父元素<li>将是.active。要使用另一个.active类,如.highlight,简单

<li><a ng-href="#/about" set-parent-active="highlight">About</a></li>
$scope.getClass = function (path) {
return String(($location.absUrl().split('?')[0]).indexOf(path)) > -1 ? 'active' : ''
}




<li class="listing-head" ng-class="getClass('/v/bookings')"><a href="/v/bookings">MY BOOKING</a></li>
<li class="listing-head" ng-class="getClass('/v/fleets')"><a href="/v/fleets">MY FLEET</a></li>
<li class="listing-head" ng-class="getClass('/v/adddriver')"><a href="/v/adddriver">ADD DRIVER</a></li>
<li class="listing-head" ng-class="getClass('/v/bookings')"><a href="/v/invoice">INVOICE</a></li>
<li class="listing-head" ng-class="getClass('/v/profile')"><a href="/v/profile">MY PROFILE</a></li>
<li class="listing-head"><a href="/v/logout">LOG OUT</a></li>

我找到了最简单的解决办法。只是比较HTML中的indexOf

var myApp = angular.module('myApp', []);


myApp.run(function($rootScope) {
$rootScope.$on("$locationChangeStart", function(event, next, current) {
$rootScope.isCurrentPath = $location.path();
});
});






<li class="\{\{isCurrentPath.indexOf('help')>-1 ? 'active' : '' }}">
<a href="/#/help/">
Help
</a>
</li>

使用Angular Version 6和Bootstrap 4.1

我能够做到如下所示。

在下面的例子中,当URL看到'/contact'时,引导活动就会被添加到html标记中。当URL改变时,它就会被删除。

<ul>
<li class="nav-item" routerLink="/contact" routerLinkActive="active">
<a class="nav-link" href="/contact">Contact</a>
</li>
</ul>
这个指令允许你在链接的时候给元素添加一个CSS类 路由激活。< / p >

阅读更多关于角的网站