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

AngularJS是否以任何方式帮助在当前页面的链接上设置active类?

我想这是有一些神奇的方式,但我似乎无法find。

我的菜单看起来像:

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

我有我的路线中的每个控制器: TasksControllerActionsController

但我不能找出一种方法来绑定到控制器a链接上的“主动”类。

任何提示?

在视图

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

在控制器上

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

有了这个任务链接将在任何以'/ tasks'开头的URL(例如'/ tasks / 1 / reports')中拥有活动类

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

但它还不完美。 注意hashbangs;)

这里是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; } 

这是一个简单的方法,适用于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引导的navbar活动类?

只是为了在辩论中添加我的两分钱,我做了一个纯粹的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 ),它至less需要example.com/#/或者example.com#/ 。 但是这会自动发生ngResource之类的。

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

在我的情况下,我通过创build一个负责导航的简单控制器来解决这个问题

 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> 

@ Renan-tomal-fernandes的答案很好,但需要一些改进才能正常工作。 事实上,即使您在另一个部分,也会始终检测到触发的主页(/)的链接。

所以我改进了一点,这是代码。 我使用Bootstrap工作,所以活动部分在<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> 

对于AngularUI路由器用户:

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

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

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

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

在阅读上面的一些精彩build议之后,我提出了这个解决scheme。 在我的特殊情况下,我试图使用Bootstrap选项卡组件作为我的菜单,但不想使用Angular-UI版本,因为我希望选项卡充当菜单,其中每个选项卡都是可书签的,而不是充当单页导航的标签。 (如果您对Angular-UI版本的引导标签看起来像什么感兴趣,请参阅http://angular-ui.github.io/bootstrap/#/tabs )。

我真的很喜欢kfis关于创build自己的指令来解决这个问题的答案,但是在每一个链接上都要有一个指令是很麻烦的。 所以我创build了我自己的Angular指令,这个指令被放置在ul 。 以防其他人试图做同样的事情,我想我会在这里发布,但正如我所说,以上的许多解决scheme也适用。 就javascript而言,这是一个稍微复杂一些的解决scheme,但是它会以最小的标记创build一个可重用的组件。

这里是ng:view的指令和路由提供程序的javascript:

 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。

你可以很简单的实现这个,下面是一个例子:

 <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" : ""; }; }); 

使用angular-ui-router的ui-sref-active指令https://github.com/angular-ui/ui-router/wiki/Quick-Reference#statename

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

我在控制器范围之外有类似的菜单问题。 不知道这是最好的解决scheme还是推荐的解决scheme,但是这对我来说是有效的。 我已经将以下内容添加到了我的应用configuration中:

 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> 

使用一个指令(因为我们在这里做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> 

我是这样做的:

 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只有基本的select器支持。 jquery包含在angular include之前的更简洁的版本看起来像这样:

 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

我对这个问题的解决scheme,在angular模板中使用route.current

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

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

然后在你的模板tasks.html你可以使用下面的ng-class指令:

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

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

这是kfis指令的一个扩展,我曾经允许不同级别的path匹配。 本质上,我发现需要匹配到一定深度的URLpath,因为精确匹配不允许嵌套和默认状态redirect。 希望这可以帮助。

  .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> 

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

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

主要特征:

  • 使用包含dynamicangular度expression式的href可以正常工作
  • 与hash-bang导航兼容
  • 与Bootstrap兼容,活动类应该应用于父节点而不是链接本身
  • 如果任何嵌套的path处于活动状态,则允许build立链接
  • 允许禁用链接,如果它不活跃

码:

 .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度expression式的简单示例,可以说$ scope.var = 2 ,如果位置是/ url / 2 ,则链接将处于活动状态:

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

引导示例,父李将获得活动类:

 <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 ),但是如果select另一个url( / url2 )将会被激活:

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

禁用链接的例子,如果它没有激活,它将有'禁用'类:

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

所有active-link- *属性都可以组合使用,因此可以实现非常复杂的条件。

如果你想要一个包装的指令的链接,而不是select每个单独的链接(可以更容易地看看在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,但是你可以很容易地改变我用filter所做的事情等等。

根据@ kfis的回答,这是评论,我的build议,最后的指示如下:

 .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路由器,我的答案有点类似于Ender2050的,但我更喜欢通过州名testing做到这一点:

 $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> 

上述指导性build议对我来说都没有用处。 如果你有这样的引导程序导航栏

 <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 。 使用像.highlight这样的替代.active类,简单地说

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

对我来说最重要的是不要改变引导程序的默认代码。 这里是我的菜单控制器,search菜单选项,然后添加我们想要的行为。

 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> 

有同样的问题。 这是我的解决scheme :

 .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' ]) 

这是我的两分钱,这工作得很好。

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

视图:

 <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() } 

我刚刚写了一个指令。

用法:

 <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'); } }); }); } }; }); 

testing:

 '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(); }); }); }); 

The route:

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

The menu 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(); ... 

The problem I found here is that the menu item is active only when the full page is loaded. When the partial view is loaded the menu doesn't change. Somebody knows why it happens?

Here is a much better way to do it

 <ul> <li ng-class="{ active: isActive('/tasks')}"><a href="/">Tasks</a></li> </ul> function tasksController($scope, $location) { $scope.isActive = function (viewLocation) { return viewLocation === $location.path(); }; } 
 $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> 

I found the easiest solution. just to compare indexOf in HTML

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>