AngularJS在为当前页面的链接设置一个活动类方面有任何帮助吗?
我想一定有什么神奇的方法可以做到,但我似乎找不到。
我的菜单是这样的:
<ul>
<li><a class="active" href="/tasks">Tasks</a>
<li><a href="/actions">Tasks</a>
</ul>
我在我的路由中为它们每个都有控制器:TasksController和ActionsController。
但是我想不出一种方法将a链接上的“活动”类绑定到控制器。
有提示吗?
这是一个扩展的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>
该指令将匹配在该指令的属性值中指定的深度级别。只是意味着它可以在其他地方多次使用。
我是这样做的:
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
我对这个问题的解决方案是使用路由。角模板中的电流。
当你在菜单中突出显示/tasks路由时,你可以将自己的属性menuItem添加到模块声明的路由中:
$routeProvider.
when('/tasks', {
menuItem: 'TASKS',
templateUrl: 'my-templates/tasks.html',
controller: 'TasksController'
);
然后在模板任务中。你可以使用以下ng-class指令:
<a href="app.html#/tasks"
ng-class="{active : route.current.menuItem === 'TASKS'}">Tasks</a>
在我看来,这比所有提出的解决方案都要干净得多。
使用指令(因为我们在这里做的是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>