AngularJS在为当前页面的链接设置一个活动类方面有任何帮助吗?
我想一定有什么神奇的方法可以做到,但我似乎找不到。
我的菜单是这样的:
<ul>
<li><a class="active" href="/tasks">Tasks</a>
<li><a href="/actions">Tasks</a>
</ul>
我在我的路由中为它们每个都有控制器:TasksController和ActionsController。
但是我想不出一种方法将a链接上的“活动”类绑定到控制器。
有提示吗?
我是这样做的:
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
我找到了最简单的解决办法。只是比较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>
如果你想把指令的链接放在一个包装器中,而不是选择每个单独的链接(这样更容易查看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,但你可以很容易地改变我所做的过滤等。
我做了一个纯angular模块(没有jQuery),它也可以处理包含数据的散列url。(例如:# /这个/ /路径?这=一些=数据)
您只需将模块作为依赖项添加并自动激活到菜单的一个祖先。是这样的:
<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/
路线:
$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();
...
我在这里发现的问题是,菜单项只有在加载整个页面时才处于活动状态。当部分视图被加载时,菜单不会改变。有人知道为什么吗?