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

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

我的菜单是这样的:

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

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

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

有提示吗?


当前回答

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

但它还不完美。小心哈希邦;)

下面是指令的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 Version 6和Bootstrap 4.1

我能够做到如下所示。

在下面的例子中,当URL看到'/contact'时,引导活动就会被添加到html标记中。当URL改变时,它就会被删除。

<ul>
<li class="nav-item" routerLink="/contact" routerLinkActive="active">
    <a class="nav-link" href="/contact">Contact</a>
</li>
</ul>

这个指令允许你在链接的时候给元素添加一个CSS类 路由激活。

在Angular网站上阅读更多信息

我做了一个纯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();
...

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

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

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>

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

主要特点:

适用于包含动态角度表达式的href 兼容散列导航 与Bootstrap兼容,其中活动类应该应用到父li而不是链接本身 允许使链接活动,如果任何嵌套的路径是活动的 允许禁用make链接,如果它不是活动的

代码:

.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表达式的简单例子,让我们输入$scope。Var = 2,那么链接将是活跃的,如果位置是/url/2:

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

Bootstrap示例,parent li将获得活动类:

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

以嵌套url为例,如果任何嵌套url是活动的,链接将是活动的(即/url/1, /url/2, url/1/2/…)

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

复杂的例子,链接指向一个url (/url1),但如果选择另一个url (/url2)将是活动的:

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

以禁用链接为例,如果它不是活动的,它将有'disabled'类:

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

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