AngularJS在为当前页面的链接设置一个活动类方面有任何帮助吗?

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

我的菜单是这样的:

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

我在我的路由中为它们每个都有控制器:TasksController和ActionsController。

但是我想不出一种方法将a链接上的“活动”类绑定到控制器。

有提示吗?


当前回答

以上的指导性建议对我都没用。如果你有一个这样的引导导航栏

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

其他回答

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

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>

如果你想把指令的链接放在一个包装器中,而不是选择每个单独的链接(这样更容易查看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,但你可以很容易地改变我所做的过滤等。

路线:

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

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

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

以上的指导性建议对我都没用。如果你有一个这样的引导导航栏

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