简体   繁体   English

如何使用Angular JS设置bootstrap navbar活动类?

[英]How to set bootstrap navbar active class with Angular JS?

If I have a navbar in bootstrap with the items 如果我在引导程序中有一个带有项目的导航栏

Home | About | Contact

How do I set the active class for each menu item when they are active? 如何为每个菜单项激活时设置活动类? That is, how can I set class="active" when the angular route is at 也就是说,当角度路径class="active"时,我如何设置class="active"

  1. #/ for home #/为家
  2. #/about for the about page #/about about about page
  3. #/contact for the contact page #/contact联系页面

A very elegant way is to use ng-controller to run a single controller outside of the ng-view: 一种非常优雅的方法是使用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>

and include in controllers.js: 并包含在controllers.js中:

function HeaderController($scope, $location) 
{ 
    $scope.isActive = function (viewLocation) { 
        return viewLocation === $location.path();
    };
}

I just wrote a directive to handle this, so you can simply add the attribute bs-active-link to the parent <ul> element, and any time the route changed, it will find the matching link, and add the active class to the corresponding <li> . 我刚刚编写了一个指令来处理这个,所以你可以简单地将属性bs-active-link到父<ul>元素,并且每当路由改变时,它将找到匹配的链接,并将active类添加到对应<li>

You can see it in action here: http://jsfiddle.net/8mcedv3b/ 你可以在这里看到它: http//jsfiddle.net/8mcedv3b/

Example HTML: 示例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: 使用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');   
                };
            });     
        });
    }
}
}]);

You can have a look at AngularStrap , the navbar directive seems to be what you are looking for: 您可以查看AngularStrap ,navbar指令似乎是您正在寻找的:

https://github.com/mgcrea/angular-strap/blob/master/src/navbar/navbar.js 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');
          }

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

To use this directive: 要使用此指令:

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

  2. Include the script on your page after bootstrap.js: 在bootstrap.js之后在您的页面上包含脚本:
    <script src="lib/angular-strap.js"></script>

  3. Add the directives to your module: 将指令添加到您的模块:
    angular.module('myApp', ['$strap.directives'])

  4. Add the directive to your navbar: 将指令添加到导航栏:
    <div class="navbar" bs-navbar>

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

Here's a simple approach that works well with Angular. 这是一个适用于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>

Within your AngularJS controller: 在AngularJS控制器中:

$scope.isActive = function (viewLocation) {
     var active = (viewLocation === $location.path());
     return active;
};

If you are working with Angular router, the RouterLinkActive directive can be used really elegantly: 如果您正在使用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>

First and foremost, this problem can be solved in a lot of ways. 首先,这个问题可以通过很多方式解决。 This way might not be the most elegant, but it cerntainly works. 这种方式可能不是最优雅的,但它确实有效。

Here is a simple solution you should be able to add to any project. 这是一个简单的解决方案,您应该可以添加到任何项目。 You can just add a "pageKey" or some other property when you configure your route that you can use to key off of. 您可以在配置可用于关闭的路由时添加“pageKey”或其他属性。 Additionally, you can implement a listener on the $routeChangeSuccess method of the $route object to listen for the successful completion of a route change. 此外,您可以在$ route对象的$ routeChangeSuccess方法上实现一个侦听器,以侦听路由更改的成功完成。

When your handler fires you get the page key, and use that key to locate elements that need to be "ACTIVE" for this page, and you apply the ACTIVE class. 当您的处理程序触发时,您获取页面键,并使用该键来查找此页面需要“ACTIVE”的元素,并应用ACTIVE类。

Keep in mind you need a way to make ALL the elements "IN ACTIVE". 请记住,您需要一种方法使所有元素“处于活动状态”。 As you can see i'm using the .pageKey class on my nav items to turn them all off, and I'm using the .pageKey_{PAGEKEY} to individually turn them on. 正如你所看到我在我的导航项目上使用.pageKey类将它们全部关闭,我正在使用.pageKey_ {PAGEKEY}来单独打开它们。 Switching them all to inactive, would be considered a naive approach, potentially you'd get better performance by using the previous route to make only active items inactive, or you could alter the jquery selector to only select active items to be made inactive. 将它们全部切换为非活动状态将被视为一种天真的方法,可能通过使用先前的路由仅使活动项处于非活动状态来获得更好的性能,或者您可以将jquery选择器更改为仅选择要使其处于非活动状态的活动项。 Using jquery to select all active items is probably the best solution because it ensures everything is cleaned up for the current route in case of any css bugs that might have been present on the previous route. 使用jquery选择所有活动项可能是最好的解决方案,因为它可以确保在前一个路径上可能存在任何css错误的情况下清除当前路由的所有内容。

Which would mean changing this line of code: 这意味着改变这行代码:

$(".pagekey").toggleClass("active", false);

to this one 对这一个

$(".active").toggleClass("active", false);

Here is some sample code: 以下是一些示例代码:

Given a bootstrap navbar of 给出一个bootstrap导航栏

<div class="navbar navbar-inverse">
    <div class="navbar-inner">
        <a class="brand" href="#">Title</a>
        <ul class="nav">
            <li><a href="#!/" class="pagekey pagekey_HOME">Home</a></li>
            <li><a href="#!/page1/create" class="pagekey pagekey_CREATE">Page 1 Create</a></li>
            <li><a href="#!/page1/edit/1" class="pagekey pagekey_EDIT">Page 1 Edit</a></li>
            <li><a href="#!/page1/published/1" class="pagekey pagekey_PUBLISH">Page 1 Published</a></li>
        </ul>
    </div>
</div>

And an angular module and controller like the following: 和角度模块和控制器如下:

<script type="text/javascript">

    function Ctrl($scope, $http, $routeParams, $location, $route) {

    }



    angular.module('BookingFormBuilder', []).
        config(function ($routeProvider, $locationProvider) {
            $routeProvider.
                when('/', { 
                   template: 'I\'m on the home page', 
                   controller: Ctrl, 
                   pageKey: 'HOME' }).
                when('/page1/create', { 
                   template: 'I\'m on page 1 create', 
                   controller: Ctrl, 
                   pageKey: 'CREATE' }).
                when('/page1/edit/:id', { 
                   template: 'I\'m on page 1 edit {id}', 
                   controller: Ctrl, pageKey: 'EDIT' }).
                when('/page1/published/:id', { 
                   template: 'I\'m on page 1 publish {id}', 
                   controller: Ctrl, pageKey: 'PUBLISH' }).
                otherwise({ redirectTo: '/' });

            $locationProvider.hashPrefix("!");
        }).run(function ($rootScope, $http, $route) {

            $rootScope.$on("$routeChangeSuccess", 
                           function (angularEvent, 
                                     currentRoute,
                                     previousRoute) {

                var pageKey = currentRoute.pageKey;
                $(".pagekey").toggleClass("active", false);
                $(".pagekey_" + pageKey).toggleClass("active", true);
            });

        });

</script>

You can actually use angular-ui-utils ' ui-route directive: 您实际上可以使用angular-ui-utilsui-route指令:

<a ui-route ng-href="/">Home</a>
<a ui-route ng-href="/about">About</a>
<a ui-route ng-href="/contact">Contact</a>

or: 要么:

Header Controller 标题控制器

/**
 * Header controller
 */
angular.module('myApp')
  .controller('HeaderCtrl', function ($scope) {
    $scope.menuItems = [
      {
        name: 'Home',
        url:  '/',
        title: 'Go to homepage.'
      },
      {
        name:   'About',
        url:    '/about',
        title:  'Learn about the project.'
      },
      {
        name:   'Contact',
        url:    '/contact',
        title:  'Contact us.'
      }
    ];
  });

Index page 索引页面

<!-- index.html: -->
<div class="header" ng-controller="HeaderCtrl">
  <ul class="nav navbar-nav navbar-right">
    <li ui-route="{{menuItem.url}}" ng-class="{active: $uiRoute}"
      ng-repeat="menuItem in menuItems">
      <a ng-href="#{{menuItem.url}}" title="{{menuItem.title}}">
        {{menuItem.name}}
      </a>
    </li>
  </ul>
</div>

If you're using ui-utils, you may also be interested in ui-router for managing partial/nested views. 如果您正在使用ui-utils,您可能也对ui-router感兴趣以管理部分/嵌套视图。

I find all of these answers a bit over complicated for me, sorry. 我发现所有这些答案对我来说有点复杂,对不起。 So I have created a small directive that should work on a per navbar basis: 所以我创建了一个小指令,应该在每个导航栏的基础上工作:

app.directive('activeLink', function () {
    return {
        link: function (scope, element, attrs) {
            element.find('.nav a').on('click', function () {
                angular.element(this)
                    .parent().siblings('.active')
                    .removeClass('active');
                angular.element(this)
                    .parent()
                    .addClass('active');
            });
        }
    };
});

Usage: 用法:

<ul class="nav navbar-nav navbar-right" active-link>
    <li class="nav active"><a href="home">Home</a></li>
    <li class="nav"><a href="foo">Foo</a></li>
    <li class="nav"><a href="bar">Bar</a></li>
</ul>

I use ng-class directive with $location to achieve it. 我使用带有$ location的ng-class指令来实现它。

<ul class="nav">
<li data-ng-class="{active: ($location.path() == '/') }">
    <a href="#/">Carpeta Amarilla</a>
</li>
<li class="dropdown" data-ng-class="{active: ($location.path() == '/auditoria' || $location.path() == '/auditoria/todos') }">
    <a class="dropdown-toggle" data-toggle="dropdown" href="#">
        Auditoria
        <b class="caret"></b>
    </a>
    <ul class="dropdown-menu pull-right">
        <li data-ng-class="{active: ($location.path() == '/auditoria') }">
            <a href="#/auditoria">Por Legajo</a>
        </li>
        <li data-ng-class="{active: ($location.path() == '/auditoria/todos') }">
            <a href="#/auditoria/todos">General</a>
        </li>
    </ul>
</li>
</ul>

It requires the navbar to be inside a main Controller with access to $location service like this: 它要求导航栏位于主控制器内,可以访问$ location服务,如下所示:

bajasApp.controller('MenuCntl', ['$scope','$route', '$routeParams', '$location', 
   function MenuCntl($scope, $route, $routeParams, $location) {
   $scope.$route = $route;
   $scope.$location = $location;
   $scope.$routeParams = $routeParams;
}]);

You can achieve this with a conditional in an angular expression, such as: 您可以使用角度表达式中的条件来实现此目的,例如:

<a href="#" class="{{ condition ? 'active' : '' }}">link</a>

That being said, I do find an angular directive to be the more "proper" way of doing it, even though outsourcing a lot of this mini-logic can somewhat pollute your code base. 话虽这么说,我确实发现一个角度指令是更“正确”的做法,即使外包很多这种迷你逻辑可能会在一定程度上污染你的代码库。

I use conditionals for GUI styling every once in a while during development, because it's a little quicker than creating directives. 我在开发期间偶尔使用条件进行GUI样式,因为它比创建指令快一点。 I couldn't tell you an instance though in which they actually remained in the code base for long. 我无法告诉你一个实例,虽然它们实际上长期存在于代码库中。 In the end I either turn it into a directive or find a better way to solve the problem. 最后,我要么把它变成一个指令,要么找到一个更好的方法来解决问题。

If you use ui-router , the following example should satisfy your needs based on @DanPantry's comment on the accepted answer without adding any controller-side code: 如果您使用ui-router ,以下示例应根据@ DanPantry对已接受答案的评论满足您的需求,而无需添加任何控制器端代码:

<div class="collapse navbar-collapse" ng-controller="HeaderController">
    <ul class="nav navbar-nav">
        <li ui-sref-active="active"><a ui-sref="app.home()" href="/">Home</a></li>
        <li ui-sref-active="active"><a ui-sref="app.dogs()" href="/dogs">Dogs</a></li>
        <li ui-sref-active="active"><a ui-sref="app.cats()" href="/cats">Cats</a></li>
    </ul>
</div>
<div ng-view></div>

You can check the docs for more info on it. 您可以查看文档以获取更多信息。

If you would rather not use AngularStrap then this directive should do the trick!. 如果你不想使用AngularStrap,那么这个指令就可以了! This is a modification of https://stackoverflow.com/a/16231859/910764 . 这是对https://stackoverflow.com/a/16231859/910764的修改。

JavaScript JavaScript的

angular.module('myApp').directive('bsNavbar', ['$location', function ($location) {
  return {
    restrict: 'A',
    link: function postLink(scope, element) {
      scope.$watch(function () {
        return $location.path();
      }, function (path) {
        angular.forEach(element.children(), (function (li) {
          var $li = angular.element(li),
            regex = new RegExp('^' + $li.attr('data-match-route') + '$', 'i'),
            isActive = regex.test(path);
          $li.toggleClass('active', isActive);
        }));
      });
    }
  };
}]);

HTML HTML

<ul class="nav navbar-nav" bs-navbar>
  <li data-match-route="/home"><a href="#/home">Home</a></li>
  <li data-match-route="/about"><a href="#/about">About</a></li>
</ul>

Note: The above HTML classes assume you are using Bootstrap 3.x 注意:上述HTML类假设您使用的是Bootstrap 3.x.

Heres my take on it. 继承人我的看法。 A little of a combination of answers found on this post. 这篇文章中的一些答案组合。 I had a slightly different case, so my solution involves separating the menu into its own template to be used within the Directive Definition Ojbect then add my navbar to the page I needed it on. 我的情况略有不同,所以我的解决方案是将菜单分成自己的模板,在指令定义Ojbect中使用,然后将我的导航栏添加到我需要的页面。 Basically, I had a login page that I didnt want to include my menu on, so I used ngInclude and insert this directive when logged in: 基本上,我有一个登录页面,我不想包含我的菜单,所以我使用ngInclude并在登录时插入此指令:

DIRECTIVE: 指示:

module.directive('compModal', function(){


return {
    restrict: 'E',
    replace: true,
    transclude: true,
    scope: true,
    templateUrl: 'templates/menu.html',
    controller: function($scope, $element, $location){
        $scope.isActive = function(viewLocation){

            var active = false;

            if(viewLocation === $location.path()){
                active = true;
            }

            return active;

        }
    }
 }
});

DIRECTIVE TEMPLATE (templates/menu.html) DIRECTIVE TEMPLATE(templates / menu.html)

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

HTML WHICH INCLUDES THE DIRECTIVE 包含指令的HTML

<comp-navbar/>

Hope this helps 希望这可以帮助

Extending myl answer, I needed this to handle an structure like this. 扩展myl答案,我需要这个来处理这样的结构。

-index -指数

-events<-active -events <-active
---event-list - -活动列表
---event-edit ---事件编辑
---event-map <-clicked --- event-map <-clicked

-places -places
---place-list ---地方列表
---place-edit ---地方编辑
---place-map ---地方地图

so instead of matching, I had to use indexOf, in order to validate children links which are formatted to match the condition. 所以我不得不使用indexOf代替匹配,以便验证格式化为匹配条件的子链接。 So for 'events': 所以对于'事件':

<li ng-class="{ active: isActive('/event')}" class="divider-vertical dropdown">


function NavController($scope, $location) { 
$scope.isActive = function (viewLocation) {
    var s=false;
    if($location.path().indexOf(viewLocation) != -1){
     s = true;
    }
    return s;
};}

This is a simple solution 这是一个简单的解决方案

<ul class="nav navbar-nav navbar-right navbar-default menu">
  <li ng-class="menuIndice == 1 ? 'active':''">
    <a ng-click="menuIndice = 1" href="#/item1">item1</a>
  </li>
  <li ng-class="menuIndice == 2 ? 'active':''">
    <a ng-click="menuIndice = 2" href="#/item2">item2</a>
  </li>
  <li ng-class="menuIndice == 3 ? 'active':''">
    <a ng-click="menuIndice = 3" href="#/item3">item3</a>
  </li>
</ul>

In conjunction with @Olivier's AngularStrap answer, I also implemented kevinknelson's answer from: https://github.com/twbs/bootstrap/issues/9013 . 结合@ Olivier的AngularStrap答案,我还实现了kevinknelson的答案: https//github.com/twbs/bootstrap/issues/9013

Natively, the Bootstrap3 navbar was not designed for a single-page (eg Angular) application and thus the menu when on a small screen was not collapsing upon click. 本地,Bootstrap3导航栏不是为单页(例如Angular)应用程序设计的,因此在小屏幕上的菜单在点击时不会崩溃。

JavaScript JavaScript的

/**
 * Main AngularJS Web Application
 */

var app = angular.module('yourWebApp', [
    'ngRoute'
]);


/**
 * Setup Main Menu
 */

app.controller('MainNavCtrl', [ '$scope', '$location', function ( $scope, $location) {
    $scope.menuItems = [
        {
            name: 'Home',
            url:  '/home',
            title: 'Welcome to our Website'
        },
        {
            name: 'ABOUT',
            url:  '/about',
            title: 'Know about our work culture'
        },
        {
            name:   'CONTACT',
            url:    '/contact',
            title:  'Get in touch with us'
        }
    ];

    $scope.isActive = function (viewLocation) {
        return viewLocation === $location.path();
    };
}]);

HTML HTML

  <div class="navbar-collapse collapse" ng-controller="MainNavCtrl">
    <ul id="add-magic-line" class="nav navbar-nav navbar-right">
      <li data-ng-class="{current_page_item: isActive('{{ menuItem.url }}')}" data-ng-repeat="menuItem in menuItems">
        <a data-ng-href="#{{menuItem.url}}" title="{{menuItem.title}}">
          {{menuItem.name}}
        </a>
      </li>
    </ul>
  </div>

Thanks to @Pylinux . 感谢@Pylinux I have used his technique and also modified it to support "one" level of drop down menu (sub ul/li), as that is what I needed. 我已经使用了他的技术,并修改了它以支持“一级”下拉菜单(sub ul / li),因为这就是我所需要的。 See it in action in the fiddle link below. 在下面的小提琴链接中查看它。

Updated Fiddle based on pylinux's answer - http://jsfiddle.net/abhatia/en4qxw6g/ 根据pylinux的答案更新了小提琴 - http://jsfiddle.net/abhatia/en4qxw6g/

I made the following three changes, in order to support one level drop down menu: 我做了以下三个更改,以支持一个级别的下拉菜单:
1. Added a class value of dd (dropdown) for "a" element under li which needs to have sub ul list. 1.为li下的“a”元素添加了dd(下拉列表)的类值,需要有子ul列表。

         <li><a class="dd">This link points to #/fun5</a>
          <ul>
            <li><a href="#/fun6?some=data">This link points to #/fun6</a>
            </li>
            <li><a href="#/fun7?some=data">This link points to #/fun7</a>
            </li>
            <li><a href="#/fun8?some=data">This link points to #/fun8</a>
            </li>
            <li><a href="#/fun9?some=data">This link points to #/fun9</a>
            </li>
          </ul>
        </li>


2. Updated Javascript to add the following new logic. 2.更新了Javascript以添加以下新逻辑。

 if(angular.element(li).parent().parent().children('a').hasClass("dd"))
 {angular.element(li).parent().parent().children('a.dd').addClass('active');}


3. Updated CSS to the add the following: 3.更新了CSS以添加以下内容:

a.active {background-color:red;}

Hopefully this will be helpful to someone looking to implement single level dropdown menu. 希望这对希望实现单级下拉菜单的人有所帮助。

Use an object as a switch variable. 使用对象作为开关变量。
You can do this inline quite simply with: 您可以通过以下方式简单地内联:

<ul class="nav navbar-nav">
   <li ng-class="{'active':switch.linkOne}" ng-click="switch = {linkOne: true}"><a href="/">Link One</a></li>
   <li ng-class="{'active':switch.linkTwo}" ng-click="switch = {link-two: true}"><a href="/link-two">Link Two</a></li>
</ul>

Each time you click on a link the switch object is replaced by a new object where only the correct switch object property is true. 每次单击链接时,switch对象都会被一个新对象替换,其中只有正确的switch对象属性为true。 The undefined properties will evaluate as false and so the elements which depend on them will not have the active class assigned. 未定义的属性将计算为false,因此依赖于它们的元素将不会分配活动类。

You can also use this active-link directive https://stackoverflow.com/a/23138152/1387163 您也可以使用此活动链接指令https://stackoverflow.com/a/23138152/1387163

Parent li will get active class when location matches /url : 当位置匹配/ url时,Parent li将获得活动类:

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

This did the trick for me: 这对我有用:

  var domain = '{{ DOMAIN }}'; // www.example.com or dev.example.com
  var domain_index =  window.location.href.indexOf(domain);
  var long_app_name = window.location.href.slice(domain_index+domain.length+1); 
  // this turns http://www.example.com/whatever/whatever to whatever/whatever
  app_name = long_app_name.slice(0, long_app_name.indexOf('/')); 
  //now you are left off with just the first whatever which is usually your app name

then you use jquery(works with angular too) to add class active 然后你使用jquery(也使用角度)来添加类活动

$('nav a[href*="' + app_name+'"]').closest('li').addClass('active');

and of course the css: 当然还有css:

.active{background:red;}

this works if you have your html like this: 这有用,如果你有这样的HTML:

<ul><li><a href="/ee">ee</a></li><li><a href="/dd">dd</a></li></ul>

this will atumatically add class active using the page url and color your background to red if your in www.somesite.com/ee thaen ee is the 'app' and it will be active 如果您在www.somesite.com/ee thaen ee是'app'并且它将处于活动状态,这将使用页面URL自然地添加类活动并将您的背景颜色设置为红色

I suggest using a directive on a link. 我建议在链接上使用指令。 Here is the fiddle. 是小提琴。

But its not perfect yet. 但它还不完美。 Watch out for the hashbangs ;) 注意hashbangs;)

Here is the javascript for directive: 这是javascript for指令:

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);
          }
        });
      }
    };
  }]);

and here is how it would be used in html: 以下是如何在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>

afterwards styling with css: 之后使用css设计样式:

.active{ color:red; }

Just to add my two cents in the debate I have made a pure angular module (no jquery), and it will also work with hash urls containing data. 只是为了在辩论中添加我的两分钱,我已经制作了一个纯角度模块(没有jquery),它也可以使用包含数据的哈希URL。 ( ig #/this/is/path?this=is&some=data ) ig #/this/is/path?this=is&some=data

You just add the module as a dependency and auto-active to one of the ancestors of the menu. 您只需将模块添加为依赖项并auto-active到菜单的其中一个祖先。 Like this: 像这样:

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

And the module look like this: 模块看起来像这样:

(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);
            }
        }
    }]);
}());

* (You can of course just use the directive part) *(您当然可以使用指令部分)

** It's also worth noticing that this doesn't work for empty hashes ( ig example.com/# or just example.com ) it needs to have at least example.com/#/ or just example.com#/ . **还值得注意的是,这不适用于空哈希( ig example.com/#或仅仅是example.com ),它至少需要具有example.com/#/或仅仅是example.com#/ But this happens automatically with ngResource and the like. 但是这会随着ngResource等自动发生。

This is long answered but I thought I'd share my way: 这个答案很长,但我想我会分享我的方式:

.run(function($rootScope, $state){
 $rootScope.$state = $state;
});

Template: 模板:

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

For those using ui-router : 对于那些使用ui-router

<ul class="nav navbar-nav">
        <li ui-sref-active="active"><a href="...">View 1</a></li>
        <li ui-sref-active="active"><a href="...">View 2</a></li>
        <li ui-sref-active="active"><a href="...">View 3</a></li>
</ul>

For exact match (eg nested states?) use $state.name === 'full/path/to/state' or ui-sref-active-eq="active" 对于完全匹配(例如嵌套状态?),使用$state.name === 'full/path/to/state'ui-sref-active-eq="active"

Here's another solution for anyone who might be interested. 对于可能感兴趣的人来说,这是另一种解决方案。 The advantage of this is it has fewer dependencies. 这样做的好处是它具有较少的依赖性。 Heck, it works without a web server too. 哎呀,没有网络服务器也可以。 So it's completely client-side. 所以它完全是客户端的。

HTML: HTML:

<nav class="navbar navbar-inverse" ng-controller="topNavBarCtrl"">
<div class="container-fluid">
    <div class="navbar-header">
        <a class="navbar-brand" href="#"><span class="glyphicon glyphicon-home" aria-hidden="true"></span></a>
    </div>
    <ul class="nav navbar-nav">
        <li ng-click="selectTab()" ng-class="getTabClass()"><a href="#">Home</a></li>
        <li ng-repeat="tab in tabs" ng-click="selectTab(tab)" ng-class="getTabClass(tab)"><a href="#">{{ tab }}</a></li>
    </ul>
</div>

Explanation: 说明:

Here we are generating the links dynamically from an angularjs model using the directive ng-repeat . 这里我们使用指令ng-repeat从angularjs模型动态生成链接。 Magic happens with the methods selectTab() and getTabClass() defined in the controller for this navbar presented below. 使用下面给出的导航栏控制器中定义的selectTab()getTabClass()方法可以selectTab()魔术。

Controller: 控制器:

angular.module("app.NavigationControllersModule", [])

// Constant named 'activeTab' holding the value 'active'. We will use this to set the class name of the <li> element that is selected.
.constant("activeTab", "active")

.controller("topNavBarCtrl", function($scope, activeTab){
    // Model used for the ng-repeat directive in the template.
    $scope.tabs = ["Page 1", "Page 2", "Page 3"];

    var selectedTab = null;

    // Sets the selectedTab.
    $scope.selectTab = function(newTab){
       selectedTab = newTab;
    };

    // Sets class of the selectedTab to 'active'.
    $scope.getTabClass = function(tab){
       return selectedTab == tab ? activeTab : "";
    };
});

Explanation: 说明:

selectTab() method is called using ng-click directive. 使用ng-click指令调用selectTab()方法。 So when the link is clicked, the variable selectedTab is set to the name of this link. 因此,单击链接时,变量selectedTab将设置为此链接的名称。 In the HTML you can see that this method is called without any argument for Home tab so that it will be highlighted when the page loads. 在HTML中,您可以看到调用此方法时没有Home选项卡的任何参数,以便在页面加载时突出显示该方法。

The getTabClass() method is called via ng-class directive in the HTML. getTabClass()方法通过HTML中的ng-class指令调用。 This method checks if the tab it is in is the same as the value of the selectedTab variable. 此方法检查它所在的选项卡是否与selectedTab变量的值相同。 If true, it returns "active" else returns "" which is applied as the class name by ng-class directive. 如果为true,则返回“active”,否则返回“”,由ng-class指令作为类名应用。 Then whatever css you have applied to class active will be applied to the selected tab. 然后,您应用于active类的任何CSS都将应用于所选选项卡。

Just you'll have to add the required active -class with required color code. 只需要添加所需的active类和所需的颜色代码。

Ex: ng-class="{'active': currentNavSelected}" ng-click="setNav" 例如: ng-class="{'active': currentNavSelected}" ng-click="setNav"

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM