Как выделить текущий пункт меню?
Помогает ли AngularJS каким-либо образом устанавливать active
class в ссылку для текущей страницы?
Я предполагаю, что это волшебный способ, но я не могу найти.
Мое меню выглядит так:
- AngularJS. Преобразование значения тега (время Unix для чтения человеком)
- Как отменить запрос $ http в AngularJS?
- Как я могу анимировать сортировку списка с помощью orderBy с помощью ng-repeat с ng-animate?
- AngularJS GET ajax call с параметрами Array
- Угловые четкие данные подформы и проверка валидации
и у меня есть controllerы для каждого из них на моих маршрутах: TasksController
и ActionsController
.
Но я не могу найти способ привязать «активный» class к ссылкам на controllerы.
Любые намеки?
- При написании директивы в AngularJS, как я могу решить, нужна ли мне новая область, новая область для детей или новая изолированная область?
- Как я могу проверить события в угловом?
- Как отказаться от подписки на широковещательное событие в angularJS. Как удалить функцию, зарегистрированную через $ on
- Улучшенный дизайн для передачи данных в другие виды ng-view и их сохранение через controllerы
- Транспортир Угловой 2 Ошибка: неизвестная ошибка: угловая не определена
- Как использовать ng-repeat для словарей в AngularJs?
- AngularJS отслеживает изменение DOM
- Не правовой JSONP API - Как получить данные без параметра CALLBACK
на вид
Tasks
на controllerе
$scope.getClass = function (path) { return ($location.path().substr(0, path.length) === path) ? 'active' : ''; }
При этом ссылка на задания будет иметь активный class в любом URL-адресе, который начинается с «/ tasks» (например, «/ tasks / 1 / reports»)
Я предлагаю использовать директиву по ссылке.
Но это еще не все. Следите за hash-бэгами;)
Вот директива 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:
после стилизации с помощью css:
.active { color: red; }
Вот простой подход, который хорошо работает с Angular.
В вашем controllerе AngularJS:
$scope.isActive = function (viewLocation) { var active = (viewLocation === $location.path()); return active; };
В этой теме есть ряд других подобных ответов.
Как настроить активный class navstar с помощью Angular JS?
Чтобы добавить свои два цента в дебаты, я создал чистый угловой модуль (без jQuery), и он также будет работать с хеш-адресами, содержащими данные. (например, #/this/is/path?this=is&some=data
)
Вы просто добавляете модуль в качестве зависимости и auto-active
одного из предков меню. Как это:
И модуль выглядит так:
(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/#
или just example.com
), в нем должно быть как минимум example.com/#/
или просто example.com#/
. Но это происходит автоматически с ngResource и т. П.
И вот скрипка: http://jsfiddle.net/gy2an/8/
В моем случае я решил эту проблему, создав простой controller, ответственный за навигацию
angular.module('DemoApp') .controller('NavigationCtrl', ['$scope', '$location', function ($scope, $location) { $scope.isCurrentPath = function (path) { return $location.path() == path; }; }]);
И просто добавив к элементу ng-class:
Существует директива ng-class
, которая связывает переменные и class css. Он также принимает объект (пары classов className vs bool).
Вот пример: http://plnkr.co/edit/SWZAqj
Ответ от @ Renan-tomal-fernandes хорош, но нужно несколько улучшений для правильной работы. Как бы то ни было, он всегда обнаруживал ссылку на домашнюю страницу (/) как вызванную, даже если вы были в другом разделе.
Поэтому я немного улучшил его, вот код. Я работаю с Bootstrap, поэтому активная часть находится в элементе
controller
$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 ""; } }
шаблон
Вот решение, которое я придумал после прочтения некоторых замечательных предложений выше. В моей конкретной ситуации я пытался использовать компонент вкладки Bootstrap в качестве своего меню, но не хотел использовать версию Angular-UI, потому что я хочу, чтобы вкладки выступали в качестве меню, где каждая вкладка имеет возможность закладки, а не вкладки, действующие как навигация для одной страницы. (См. http://angular-ui.github.io/bootstrap/#/tabs, если вас интересует, как выглядит вкладка загрузочных бутграмм с угловым UI).
Мне очень понравился ответ 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 вы просто:
Вот для него плукер: http://plnkr.co/edit/xwGtGqrT7kWoCKnGDHYN?p=preview .
Вы можете реализовать это очень просто, вот пример:
И ваш controller должен быть таким:
app.controller("MenuCtrl", function($scope, $location) { $scope.menuClass = function(page) { var current = $location.path().substring(1); return page === current ? "active" : ""; }; });
использовать директиву ui-sref-active углового ui-router https://github.com/angular-ui/ui-router/wiki/Quick-Reference#statename
У меня была аналогичная проблема с меню, расположенным вне области controllerа. Не уверен, что это лучшее решение или рекомендуется, но это то, что сработало для меня. Я добавил в конфигурацию своего приложения следующее:
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; } } });
Тогда в представлении у меня есть:
Home ...
Используя директиву (поскольку мы делаем манипуляции с DOM здесь), вероятно, наиболее близким к тому, чтобы делать вещи «угловым способом»:
$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: '{{time.label}} ', 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 будет выглядеть так:
Я сделал это так:
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}; });
Это позволяет вам иметь ссылки в разделе, в котором есть управляющая дорожка:
Для меня этот подход кажется намного более чистым, чем другие.
Кроме того, если вы используете jQuery, вы можете сделать его намного опрятным, потому что jQlite поддерживает только базовую селекторную поддержку. Более чистая версия с 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
Мое решение этой проблемы, используйте route.current
в угловом шаблоне.
Поскольку у вас есть маршрут https://stackoverflow.com/tasks
для выделения в вашем меню, вы можете добавить свое собственное свойство menuItem
к маршрутам, объявленным вашим модулем:
$routeProvider. when('https://stackoverflow.com/tasks', { menuItem: 'TASKS', templateUrl: 'my-templateshttps://stackoverflow.com/tasks.html', controller: 'TasksController' );
Затем в вашем шаблоне tasks.html
вы можете использовать следующую директиву ng-class
:
Tasks
На мой взгляд, это намного чище, чем все предлагаемые решения.
Вот расширение по директиве 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"); } }); } }; }]);
И вот как я использую ссылку
Эта директива будет соответствовать уровню глубины, указанному в значении атрибута для директивы. Просто означает, что он может использоваться в другом месте много раз.
Вот еще одна директива для выделения активных ссылок.
Ключевая особенность:
- Прекрасно работает с href, который содержит динамические угловые выражения
- Совместим с хешированием
- Совместимость с Bootstrap, где активный class должен применяться к родительскому элементу, а не к самой ссылке
- Позволяет активировать ссылку, если какой-либо вложенный путь активен
- Позволяет отключить связь, если она не активна
Код:
.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); } ); } }; } ]);
Применение:
Простой пример с угловым выражением, скажем $ scope.var = 2 , тогда ссылка будет активна, если location / url / 2 :
Пример Bootstrap, parent li получит активный class:
Пример с вложенными URL-адресами, ссылка будет активна, если какой-либо вложенный URL-адрес активен (т.е. / url / 1 , / url / 2 , url / 1/2 / … )
Сложный пример: ссылка указывает на один url ( / url1 ), но будет активна, если выбран другой ( / url2 ):
Пример с отключенной ссылкой, если он неактивен, он будет иметь class «disabled» :
Все атрибуты active-link- * могут использоваться в любой комбинации, поэтому могут быть реализованы очень сложные условия.
Если вы хотите, чтобы ссылки для директивы в обертке, а не выбор каждой отдельной ссылки (упрощает просмотр области в 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); }); } }; } ]);
Разметка будет всего лишь:
Я должен также упомянуть, что в этом примере я использую «полный жир» jQuery, но вы можете легко изменить то, что я сделал с фильтрацией, и так далее.
Согласно ответу @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:
после стилизации с помощью css:
.active { color: red; }
Для тех, кто использует ui-router, мой ответ несколько похож на Ender2050, но я предпочитаю делать это с помощью тестирования имени штата:
$scope.isActive = function (stateName) { var active = (stateName === $state.current.name); return active; };
соответствующий HTML:
Ни одно из приведенных выше рекомендаций не было полезным для меня. Если у вас есть загрузочный navbar, как это
(это может быть $ yo angular
запуск в $ yo angular
), то вы хотите добавить. .active
в родительский class classа
, а не сам элемент; т.е.
. Поэтому я написал следующее:
.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
по умолчанию, поэтому не нужно устанавливать
About
и родительский элемент
будет .active
когда ссылка активна. Чтобы использовать альтернативный .active
class, например .highlight
, просто
About
Для меня самое главное не было менять код загрузки bootstrap. Здесь мой controller меню выполняет поиск опций меню, а затем добавляет требуемое поведение.
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'; } } }
была такая же проблема. Вот мое решение :
.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' ])
Вот мои два цента, это работает отлично.
ПРИМЕЧАНИЕ. Это не соответствует дочерним страницам (это то, что мне нужно).
Посмотреть:
Some link
controller:
// make sure you inject $location as a dependency $scope.isCurrentLocation = function(path){ return path === $location.path() }
Я просто написал для этого директиву.
Применение:
Реализация:
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('
-Foo '); 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('Foo '); 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('Foo '); 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('Foo '); 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(); }); }); });'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('
Foo '); 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('Foo '); 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('Foo '); 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('Foo '); 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:
Контроллер:
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
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' : '' } MY BOOKING MY FLEET ADD DRIVER INVOICE MY PROFILE LOG OUT
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(); }); }); Help