如何在Angular 2中设置Bootstrap导航栏的“active”类?

80

我该如何在Angular 2中设置Bootstrap导航栏的"active"类?我只找到了Angular 1的方法

当我进入关于页面时,将class="active"添加到关于中,并从主页中移除class="active"

<ul class="nav navbar-nav">
    <li class="active"><a [routerLink]="['Home']">Home</a></li>
    <li><a [routerLink]="['About']">About</a></li></li>
</ul>

谢谢


1
虽然它不完全符合您的要求,但我相信当链接处于活动状态时,routerLink会自动将类设置为router-link-active。因此,如果在您的项目中可能的话,我建议在您的CSS中使用类.router-link-active。 - Gabu
11个回答

176
如果您使用新的3.0.0组件路由(https://github.com/angular/vladivostok),则可以使用< strong>routerLinkActive 指令。无需进一步的JavaScript。
<ul class="nav navbar-nav">
  <li [routerLinkActive]="['active']"> <a [routerLink]="['one']">One</a></li>
  <li [routerLinkActive]="['active']"> <a [routerLink]="['second']">Second</a></li>
</ul>

我使用了 "@angular/router": "^3.0.0-alpha.7"。


1
Dart 有任何对应的东西吗? - Franklin Yu
1
如果当前路由确实处于活动状态,@superjos 可能允许添加多个类/值。 - jarodsmk
1
简单而完美的答案,谢谢你。 - Hidayt Rahman
1
@superjos 除了n15m0-jk的答案之外,您还可以为一个类添加routerLinkActive="active"。 - Hugo Passos
谢谢兄弟,回答简洁完美 <3 - Junaid khan
显示剩余3条评论

71

Bert Deterd's的回答是正确的,但还有一点可以补充。

如果一条路由是另一条路由的子字符串,您将会看到类似于这样的情况发生:2个活动锚点

您可以添加以下内容以仅匹配精确路由:

[routerLinkActiveOptions]="{exact:true}"

完整示例:

<ul class="nav navbar-nav">
  <li [routerLinkActive]="['active']" [routerLinkActiveOptions]="{exact:true}">
    <a [routerLink]="['/']">Home</a>
  </li>
  <li [routerLinkActive]="['active']" [routerLinkActiveOptions]="{exact:true}">
    <a [routerLink]="['/about']">About</a>
  </li>
  <li [routerLinkActive]="['active']" [routerLinkActiveOptions]="{exact:true}">
    <a [routerLink]="['/calendar']">Calendar</a>
  </li>
</ul>

1
我在处理主页路由时遇到了这个问题,因为它只是应用程序域(空字符串),所以它总是显示为活动状态。 - Vic
我遇到了一个问题,即在链接之外点击(例如在网页中心)会使li不活动。这是因为我将angular指令放在锚标签而不是a标签中。在我的想法中,这没有任何区别,但按照你的方式运行,也许这个评论可以帮助其他人。谢谢! - Mese
完美的答案 - Sushin Pv
3
你的 [routerLinkActiveOptions]="{exact:true}" 参数真的很有帮助,感谢。对于那些想知道它的作用的人来说,它可以确保当用户在其他页面上时,主页的 ['/'] 路径不会被误认为与当前路径匹配而激活 active class。 - Ali Kazai
了不起!谢谢! - PhillipJacobs

10

对于最新版本的 Angular2 RC4,以下简单代码可以使用:

      <li [class.active]="router.url==='/about'"><a [routerLink]="['/about']">About</a></li>

使用import {Router} from "@angular/router";,并将路由器放置在构造函数中。


对我来说一切正常(Y)。但是我有一个疑问,如果是下拉菜单该怎么办..例如 "<li class="dropdown"><ul> <li><a></li></ul></li>."。如果出现这种情况我们应该怎么做? - Deepak Pookkote

6
使用 isRouteActivegenerate 方法,这两个方法都来自 Router 类。
根据文档:

generate(linkParams: any[]) : Instruction

基于提供的 Route Link DSL 生成一个指令。

并且

isRouteActive(instruction: Instruction) : boolean

给定一个指令,如果该指令当前处于激活状态,则返回 true,否则返回 false。

<li [class.active]="router.isRouteActive(router.generate(['/Home']))">
   <a [routerLink]="['/Home']">Home</a>
</li>

4
在Angular2 rc1中,这必须更改为类似于这样的内容:[class.active]="router.urlTree.contains(router.createUrlTree(['Home']))"。此外,我想指出,必须像这样将路由器注入组件中:constructor(public router: Router) - František Žiačik
1
为了检查根路径 /,我使用了 router.urlTree._root.children.length == 0。看起来有点不太好,但是可以用。 - Sam Barnum
这里简单说明一下:如果你的组件构造函数长成这样:constructor (private router:Router),那么以上的代码都能正常工作,但是你无法生成生产环境代码,因为router被声明为私有属性。 - jarodsmk

5
这就做到了(使用RC5)。
<li [class.active]="homeLink.classList.contains('active')">
    <a #homeLink routerLink="/home" routerLinkActive="active">Home</a>
</li>

3

在RC2上,这个方法对我无效。我最终使用了以下方法:

   <li  (click)="setActive('home')" class="{{getActive('home')}}"> <a [routerLink]="['/FullScreen']">Home</a></li>

并在代码后端进行跟踪

    currentChoice: string = "home";

   setActive(choice: string): void{
       this.currentChoice = choice;
   }

   getActive(choice: string) : string{
       if(this.currentChoice == choice)
            return "active";
       else
            return "not";

   }

2
在"@angular/router": "^3.3.1"中,与先前版本的区别在于routerLinkActive中的括号。
[routerLinkActive]="['active']"

在最终版本中,ng2 会发出警告,请移除括号。
routerLinkActive="active"

1
在存在多个链接的情况下,请尝试这样做。
<ul class="navbar-nav ml-auto"> 
<li class="nav-item " routerLink="" routerLinkActive="active" [routerLinkActiveOptions]="{exact:true}">
<a class="nav-link" routerLink="">Home </a></li>
<li class="nav-item" [routerLinkActive]="['active']">
<a class="nav-link" routerLink="/aboutus">About</a></li>
<li class="nav-item" [routerLinkActive]="['active']">
<a class="nav-link" routerLink="/gallery">Gallery</a>
 </li>
<li class="nav-item" [routerLinkActive]="['active']">
<a class="nav-link" routerLink="/contactus">Contact Us</a>
</li>
</ul>

0

<a routerLink="/user/bob" routerLinkActive="active-link" [routerLinkActiveOptions]="{exact:
true}">Bob</a>


0
import { Directive, HostListener, ElementRef, HostBinding, Renderer2 } from '@angular/core';

@Directive({
  selector: '[appNavDropdown]'
})
export class NavDropdownDirective {
  isOpen:boolean =false;
  counter:number = 0;
  constructor(private el: ElementRef, private render: Renderer2) { }

  @HostBinding('class.open') get opened() {
    return this.isOpen;
  }

  @HostListener('click') onmouseClick()
  {
    this.counter++
    console.log();
    if(this.counter % 2 == 1)//odd
    {
      let part = this.render.parentNode(this.el.nativeElement);
      this.render.addClass(part,'open');
      this.isOpen = true;
    }else{
      let part = this.render.parentNode(this.el.nativeElement);
      this.render.removeClass(part,'open');
      this.isOpen = false;
    }
  }
  // @HostListener('mouseleave') onmouseLeave()
  // {
  //   let part = this.render.parentNode(this.el.nativeElement);
  //   this.render.removeClass(part,'open');
  //   this.isOpen = false;
  // }

  toggleClose() {
    // let part = this.render.parentNode(this.el.nativeElement)
    //this.menuclick = false;

  }
  toggle() {
    this.el.nativeElement.classList.toggle('open');
  }
}

/**
* Allows the dropdown to be toggled via click.
*/
@Directive({
  selector: '[appNavDropdownToggle]'
})
export class NavDropdownToggleDirective {
  constructor(private dropdown: NavDropdownDirective) { }

  @HostListener('click', ['$event'])
  toggleOpen($event: any) {
    console.log($event)
    $event.preventDefault();
  //  this.dropdown.toggleClose()
   this.dropdown.toggle();
  }
}

export const NAV_DROPDOWN_DIRECTIVES = [NavDropdownDirective, NavDropdownToggleDirective];

请考虑添加一些解释。 - Sunil

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接