如何使用 Angular JS 设置引导导航栏活动类?

IT技术 javascript twitter-bootstrap angularjs angularjs-directive navbar
2021-01-16 03:59:36

如果我在引导程序中有一个带有项目的导航栏

Home | About | Contact

当每个菜单项处于活动状态时,如何为它们设置活动类?也就是说,我如何设置class="active"角度路线在

  1. #/ 为家
  2. #/about 关于页面
  3. #/contact 对于联系页面
6个回答

一种非常优雅的方法是使用 ng-controller 在 ng-view 之外运行单个控制器:

<div class="collapse navbar-collapse" ng-controller="HeaderController">
    <ul class="nav navbar-nav">
        <li ng-class="{ active: isActive('/')}"><a href="/">Home</a></li>
        <li ng-class="{ active: isActive('/dogs')}"><a href="/dogs">Dogs</a></li>
        <li ng-class="{ active: isActive('/cats')}"><a href="/cats">Cats</a></li>
    </ul>
</div>
<div ng-view></div>

并包含在controllers.js 中:

function HeaderController($scope, $location) 
{ 
    $scope.isActive = function (viewLocation) { 
        return viewLocation === $location.path();
    };
}
这完成了工作,但它很难elegant- 例如/dogs必须在调用中复制路由名称isActive('/dogs')
2021-03-15 03:59:36
我建议return $location.path().indexOf(viewLocation) == 0;改为使用,以便您也可以捕获带有参数的页面
2021-03-17 03:59:36
如果您使用的是 UI 路由器,那么您可以使用ui-sref-active/ui-sref-active-eq指令,即。ui-sref-active-eq='active'ui-sref-active='active'达到相同的结果
2021-03-22 03:59:36
由于我是新手,如果您能提供一个关于如何将其放入标头指令的示例,我将不胜感激。
2021-03-27 03:59:36
@SvenHecht 该逻辑的问题在于主页链接 (/) 将匹配所有其他路径。
2021-04-05 03:59:36

我刚刚写了一个指令来处理这个,所以你可以简单地将属性添加bs-active-link到父<ul>元素,并且任何时候路由发生变化,它都会找到匹配的链接,并将active添加到相应的<li>.

你可以在这里看到它的实际效果:http : //jsfiddle.net/8mcedv3b/

示例 HTML:

<ul class="nav navbar-nav" bs-active-link>
  <li><a href="/home">Home</a></li>
  <li><a href="/contact">Contact</a></li>
</ul>

Javascript:

angular.module('appName')
.directive('bsActiveLink', ['$location', function ($location) {
return {
    restrict: 'A', //use as attribute 
    replace: false,
    link: function (scope, elem) {
        //after the route has changed
        scope.$on("$routeChangeSuccess", function () {
            var hrefs = ['/#' + $location.path(),
                         '#' + $location.path(), //html5: false
                         $location.path()]; //html5: true
            angular.forEach(elem.find('a'), function (a) {
                a = angular.element(a);
                if (-1 !== hrefs.indexOf(a.attr('href'))) {
                    a.parent().addClass('active');
                } else {
                    a.parent().removeClass('active');   
                };
            });     
        });
    }
}
}]);
为了我自己的目的,不得不稍微调整一下,但很棒的答案!很容易理解。
2021-03-24 03:59:36
我比接受的答案更喜欢这个,因为没有重复的配置数据,即路由本身只保留在一个地方,这只是有效..
2021-03-29 03:59:36
为我工作使用 scope.$watch("$routeChangeSuccess", function () { .... 而不是 scope.$on("$routeChangeSuccess", function () {....
2021-04-02 03:59:36

你可以看看AngularStrap,导航栏指令似乎是你正在寻找的:

https://github.com/mgcrea/angular-strap/blob/master/src/navbar/navbar.js

.directive('bsNavbar', function($location) {
  'use strict';

  return {
    restrict: 'A',
    link: function postLink(scope, element, attrs, controller) {
      // Watch for the $location
      scope.$watch(function() {
        return $location.path();
      }, function(newValue, oldValue) {

        $('li[data-match-route]', element).each(function(k, li) {
          var $li = angular.element(li),
            // data('match-rout') does not work with dynamic attributes
            pattern = $li.attr('data-match-route'),
            regexp = new RegExp('^' + pattern + '$', ['i']);

          if(regexp.test(newValue)) {
            $li.addClass('active');
          } else {
            $li.removeClass('active');
          }

        });
      });
    }
  };
});

要使用此指令:

  1. http://mgcrea.github.io/angular-strap/下载 AngularStrap

  2. 在 bootstrap.js 之后在页面上包含脚本:
    <script src="lib/angular-strap.js"></script>

  3. 将指令添加到您的module中:
    angular.module('myApp', ['$strap.directives'])

  4. 将指令添加到您的导航栏:
    <div class="navbar" bs-navbar>

  5. 在每个导航项上添加正则表达式:
    <li data-match-route="/about"><a href="#/about">About</a></li>

这对我来说非常有效 - 但是我必须进行一项更改,根据mgcrea.github.io/angular-strap添加到您的module的指令mgcrea.ngStrap不是$strap.directives
2021-03-16 03:59:36
@Lucio 该方法需要 2 个参数 - jQuery(selector, context) - 第二个参数是传递选择器的上下文,父 DOM 元素或另一个 jQuery 对象本身 -在这里阅读更多
2021-03-23 03:59:36
为什么将element变量传递给 jquery 选择器?$('...', element)
2021-03-31 03:59:36
谢谢。这帮助我修复了我自己的指令(对我来说缺少的洞察力是scope.$watch
2021-04-06 03:59:36

这是一种适用于 Angular 的简单方法。

<ul class="nav navbar-nav">
    <li ng-class="{ active: isActive('/View1') }"><a href="#/View1">View 1</a></li>
    <li ng-class="{ active: isActive('/View2') }"><a href="#/View2">View 2</a></li>
    <li ng-class="{ active: isActive('/View3') }"><a href="#/View3">View 3</a></li>
</ul>

在你的 AngularJS 控制器中:

$scope.isActive = function (viewLocation) {
     var active = (viewLocation === $location.path());
     return active;
};
不错的做法。我稍微修改了一下 - 使用了 ng-class 指令(ng-class={active: isActive('/View1')}) 并更新了 isActive 函数以返回 true/false 而不是类名本身。
2021-03-13 03:59:36
我已经像你的例子一样复制了所有东西,对我来说 $location.path() 没有用......切换到 $location.url(),它起作用了!
2021-04-03 03:59:36

如果您正在使用 Angular 路由器,则可以非常优雅地使用RouterLinkActive 指令

<ul class="navbar-nav">
  <li class="nav-item"><a class="nav-link" routerLink="home" routerLinkActive="active">Home</a></li>
  <li class="nav-item"><a class="nav-link" routerLink="gallery" routerLinkActive="active">Gallery</a></li>
  <li class="nav-item"><a class="nav-link" routerLink="pricing" routerLinkActive="active">Prices</a></li>
  <li class="nav-item"><a class="nav-link" routerLink="contact" routerLinkActive="active">Contact</a></li>
</ul>
注意:如果您/用作您的主页,routerLinkActive将认为它对任何以 开头的 URL 有效/,例如/foo//foo/bar等。要完全匹配,您需要routerLinkActive="active" [routerLinkActiveOptions]="{exact:true}".
2021-03-14 03:59:36
我认为这应该是公认的答案(至少对于 angular 2+),为什么要实现一些已经实现的东西?但是对于 Bootstrap 3.3,active该类应该在<li>(您可以将 routerLinkActive 与 routerLink 或其父级放在一起)
2021-03-22 03:59:36