在Angular 2中,你如何确定主动路线?

注意: 这里有很多不同的答案,而且大多数都是有效的。 事实上,Angular 2团队已经改变了路由器,有些改变了很多次。 最终成为Angular 2中路由器的路由器3.0版本打破了许多这些解决scheme,但提供了一个非常简单的解决scheme。 从RC.3开始,首选解决scheme是使用[routerLinkActive] , 如此答案中所示。

在Angular 2应用程序(2.0.0-beta.0发行版中的当前版本)中,如何确定当前活动的路由是什么?

我正在使用Bootstrap 4的一个应用程序,我需要一种方式来标记导航链接/button,当它们的关联组件被显示在一个<router-output>标签。

我意识到,当点击其中一个button时,我可以自己保持状态,但是这不会涵盖多个path进入相同path的情况(例如主要导航菜单以及主要组件中的本地菜单)。

任何build议或链接,将不胜感激。 谢谢。

使用新的Angular路由器 ,您可以为[routerLinkActive]="['your-class-name']"所有链接添加[routerLinkActive]="['your-class-name']"属性:

 <a [routerLink]="['/home']" [routerLinkActive]="['is-active']">Home</a> 

或者如果只需要一个类,则是简化的非数组格式:

 <a [routerLink]="['/home']" [routerLinkActive]="'is-active'">Home</a> 

请参阅文档不routerLinkActive指令了解更多信息。 (我主要通过反复试验来了解这一点。)

更新:现在可以在这里find更好的routerLinkActive指令的文档。 (感谢@Victor Hugo Arango A.在下面的评论中。)

我已经在另一个问题上回答了这个问题,但我相信这也可能与此相关。 这里有一个链接到原来的答案: angular2:如何确定主动路线与参数?

我一直在尝试设置活动类,而不必确切知道当前位置(使用路由名称) 。 到目前为止,最好的解决scheme是使用Router类中可用的函数isRouteActive 。

router.isRouteActive(instruction): Boolean接受一个参数,它是一个路由Instruction对象,并返回truefalse无论该指令对于当前路由是否成立。 您可以使用Router的生成(linkParams:Array)生成路由Instruction 。 LinkParams遵循与传递给routerLink指令的值完全相同的格式(例如router.isRouteActive(router.generate(['/User', { user: user.id }])) )。

这是RouteConfig的样子(我已经调整了一下来显示params的用法)

 @RouteConfig([ { path: '/', component: HomePage, name: 'Home' }, { path: '/signin', component: SignInPage, name: 'SignIn' }, { path: '/profile/:username/feed', component: FeedPage, name: 'ProfileFeed' }, ]) 

视图看起来像这样:

 <li [class.active]="router.isRouteActive(router.generate(['/Home']))"> <a [routerLink]="['/Home']">Home</a> </li> <li [class.active]="router.isRouteActive(router.generate(['/SignIn']))"> <a [routerLink]="['/SignIn']">Sign In</a> </li> <li [class.active]="router.isRouteActive(router.generate(['/ProfileFeed', { username: user.username }]))"> <a [routerLink]="['/ProfileFeed', { username: user.username }]">Feed</a> </li> 

到目前为止,这一直是我的首选解决scheme,也可能对您有所帮助。

我解决了我在这个链接遇到的问题,我发现有一个简单的解决scheme,您的问题。 你可以在你的样式中使用router-link-active

 @Component({ styles: [`.router-link-active { background-color: red; }`] }) export class NavComponent { } 

您可以通过将Location对象注入控制器并检查path()来检查当前路由,如下所示:

 class MyController { constructor(private location:Location) {} ... location.path(); ... } 

您将必须确保首先导入它:

 import {Location} from "angular2/router"; 

然后可以使用正则expression式来匹配返回的path,以查看哪个路由处于活动状态。 请注意,无论您使用的是哪种LocationStrategyLocation类都会返回规范化的path。 所以,即使你使用HashLocationStragegy ,返回的path仍然是/foo/bar的forms, 而不是 #/foo/bar

小改进@ alex-correia-santos答案根据https://github.com/angular/angular/pull/6407#issuecomment-190179875

 import {Router, RouteConfig, ROUTER_DIRECTIVES} from 'angular2/router'; // ... export class App { constructor(private router: Router) { } // ... isActive(instruction: any[]): boolean { return this.router.isRouteActive(this.router.generate(instruction)); } } 

像这样使用它:

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

你如何确定当前的活动路线是什么?

更新:根据Angular2.4.x更新

 constructor(route: ActivatedRoute) { route.snapshot.params; // active route's params route.snapshot.data; // active route's resolved data route.snapshot.component; // active route's component route.snapshot.queryParams // The query parameters shared by all the routes } 

查看更多…

下面是在Angular version 2.0.0-rc.1添加活动路由样式的一个完整示例,它考虑了null根path(例如path: '/'

app.component.ts – >路由

 import { Component, OnInit } from '@angular/core'; import { Routes, Router, ROUTER_DIRECTIVES } from '@angular/router'; import { LoginPage, AddCandidatePage } from './export'; import {UserService} from './SERVICES/user.service'; @Component({ moduleId: 'app/', selector: 'my-app', templateUrl: 'app.component.html', styleUrls: ['app.component.css'], providers: [UserService], directives: [ROUTER_DIRECTIVES] }) @Routes([ { path: '/', component: AddCandidatePage }, { path: 'Login', component: LoginPage } ]) export class AppComponent { //implements OnInit constructor(private router: Router){} routeIsActive(routePath: string) { let currentRoute = this.router.urlTree.firstChild(this.router.urlTree.root); // eg 'Login' or null if route is '/' let segment = currentRoute == null ? '/' : currentRoute.segment; return segment == routePath; } } 

app.component.html

 <ul> <li [class.active]="routeIsActive('Login')"><a [routerLink]="['Login']" >Login</a></li> <li [class.active]="routeIsActive('/')"><a [routerLink]="['/']" >AddCandidate</a></li> </ul> <route-outlet></router-outlet> 

解决scheme为Angular2 RC 4:

 import {containsTree} from '@angular/router/src/url_tree'; import {Router} from '@angular/router'; export function isRouteActive(router: Router, route: string) { const currentUrlTree = router.parseUrl(router.url); const routeUrlTree = router.createUrlTree([route]); return containsTree(currentUrlTree, routeUrlTree, true); } 

要标记主动路由routerLinkActive可以使用

 <a [routerLink]="/user" routerLinkActive="some class list">User</a> 

这也适用于其他元素

 <div routerLinkActive="some class list"> <a [routerLink]="/user">User</a> </div> 

如果部分匹配也应该标记使用

 routerLinkActive="some class list" [routerLinkActiveOptions]="{ exact: false }" 

据我所知, exact: false在RC.4中将是默认的

以下是根据当前路线使用RouteData来设置menuBar项目的方法:

RouteConfig包含选项卡(当前路线)的数据:

 @RouteConfig([ { path: '/home', name: 'Home', component: HomeComponent, data: {activeTab: 'home'}, useAsDefault: true }, { path: '/jobs', name: 'Jobs', data: {activeTab: 'jobs'}, component: JobsComponent } ]) 

一块布局:

  <li role="presentation" [ngClass]="{active: isActive('home')}"> <a [routerLink]="['Home']">Home</a> </li> <li role="presentation" [ngClass]="{active: isActive('jobs')}"> <a [routerLink]="['Jobs']">Jobs</a> </li> 

类:

 export class MainMenuComponent { router: Router; constructor(data: Router) { this.router = data; } isActive(tab): boolean { if (this.router.currentInstruction && this.router.currentInstruction.component.routeData) { return tab == this.router.currentInstruction.component.routeData.data['activeTab']; } return false; } } 

在Angular 2 RC中, Router不再定义isRouteActivegenerate方法。

urlTree – 返回当前的url树。

createUrlTree(commands: any[], segment?: RouteSegment) – 将一个命令数组应用于当前的url树,并创build一个新的url树。

尝试以下

 <li [class.active]= "router.urlTree.contains(router.createUrlTree(['/SignIn', this.routeSegment]))"> 

请注意, routeSegment : RouteSegment必须注入到组件的构造函数中。

现在我用引导程序4使用rc.4,这对我来说是完美的:

  <li class="nav-item" routerLinkActive="active" [routerLinkActiveOptions]="{exact: true}"> <a class="nav-link" [routerLink]="['']">Home</a> </li> 

这将工作的url:/家庭

Router类的一个实例实际上是一个Observable,每当它改变时它就返回当前path。 这是我如何做到的:

 export class AppComponent implements OnInit { currentUrl : string; constructor(private _router : Router){ this.currentUrl = '' } ngOnInit() { this._router.subscribe( currentUrl => this.currentUrl = currentUrl, error => console.log(error) ); } isCurrentRoute(route : string) : boolean { return this.currentUrl === route; } } 

然后在我的HTML:

 <a [routerLink]="['Contact']" class="item" [class.active]="isCurrentRoute('contact')">Contact</a> 

另一个解决方法。 在Angular Router V3 Alpha中更容易。 通过注入路由器

 import {Router} from "@angular/router"; export class AppComponent{ constructor(private router : Router){} routeIsActive(routePath: string) { return this.router.url == routePath; } } 

用法

 <div *ngIf="routeIsActive('/')"> My content </div> 

在Angular2 RC2中,你可以使用这个简单的实现

 <a [routerLink]="['/dashboard']" routerLinkActive="active">Dashboard</a> 

这会将active类添加到具有匹配url的元素,请在此处阅读更多内容

下面是所有到目前为止发布的Angular 2 RC版本的这个问题的答案:

RC4和RC3

为了应用类链接或链接的祖先:

 <li routerLinkActive="active"><a [routerLink]="['/home']">Home</a></li> 

/ home应该是URL,而不是路由的名称,因为在路由器v3中,Route属性不再存在路由对象。

更多关于这个链接的 routerLinkActive指令。

为了根据当前路线对任何div应用class:

  • 将路由器注入组件的构造器。
  • 用户router.url进行比较。

例如

 <nav [class.transparent]="router.url==('/home')"> </nav> 

RC2和RC1

使用router.isRouteActive和class。*的组合。 例如基于Home Route来应用活动课程。

名称和url都可以传入router.generate。

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

在简单的情况下使用routerLinkActive是有好处的,当有一个链接,你想申请一些类。 但在更复杂的情况下,您可能没有routerLink或需要更多的东西,您可以创build和使用pipe道

 @Pipe({ name: "isRouteActive", pure: false }) export class IsRouteActivePipe implements PipeTransform { constructor(private router: Router, private activatedRoute: ActivatedRoute) { } transform(route: any[], options?: { queryParams?: any[], fragment?: any, exact?: boolean }) { if (!options) options = {}; if (options.exact === undefined) options.exact = true; const currentUrlTree = this.router.parseUrl(this.router.url); const urlTree = this.router.createUrlTree(route, { relativeTo: this.activatedRoute, queryParams: options.queryParams, fragment: options.fragment }); return containsTree(currentUrlTree, urlTree, options.exact); } } 

然后:

 <div *ngIf="['/some-route'] | isRouteActive">...</div> 

并且不要忘记在pipe道依赖中包含pipe道;)

正如接受的答案的注释之一所述, routerLinkActive指令也可以应用于实际<a>标签的容器。

因此,例如使用Twitter Bootstrap选项卡将活动类应用于包含链接的<li>标记:

 <ul class="nav nav-tabs"> <li role="presentation" routerLinkActive="active"> <a routerLink="./location">Location</a> </li> <li role="presentation" routerLinkActive="active"> <a routerLink="./execution">Execution</a> </li> </ul> 

漂亮整洁! 我想这个指令检查标签的内容,并用routerLink指令寻找一个<a>标签。

对于Angular版本4+,您不需要使用任何复杂的解决scheme。 你可以简单地使用[routerLinkActive]="'is-active'"

对于bootstrap 4导航链接的示例:

  <ul class="navbar-nav mr-auto"> <li class="nav-item" routerLinkActive="active"> <a class="nav-link" routerLink="/home">Home</a> </li> <li class="nav-item" routerLinkActive="active"> <a class="nav-link" routerLink="/about-us">About Us</a> </li> <li class="nav-item" routerLinkActive="active"> <a class="nav-link " routerLink="/contact-us">Contact</a> </li> </ul> 

我正在寻求一种方法来使用Angular2的Twitter Bootstrap风格的导航,但无法将active类应用到所选链接的父元素。 发现@ alex-correia-santos的解决scheme完美无缺!

包含您的选项卡的组件必须导入路由器并在其构造函数中定义它,然后才能进行必要的调用。

这里是我的实现的简化版本…

 import {Component} from 'angular2/core'; import {Router, RouteConfig, ROUTER_DIRECTIVES} from 'angular2/router'; import {HomeComponent} from './home.component'; import {LoginComponent} from './login.component'; import {FeedComponent} from './feed.component'; @Component({ selector: 'my-app', template: ` <ul class="nav nav-tabs"> <li [class.active]="_r.isRouteActive(_r.generate(['Home']))"> <a [routerLink]="['Home']">Home</a> </li> <li [class.active]="_r.isRouteActive(_r.generate(['Login']))"> <a [routerLink]="['Login']">Sign In</a> </li> <li [class.active]="_r.isRouteActive(_r.generate(['Feed']))"> <a [routerLink]="['Feed']">Feed</a> </li> </ul>`, styleUrls: ['app/app.component.css'], directives: [ROUTER_DIRECTIVES] }) @RouteConfig([ { path:'/', component:HomeComponent, name:'Home', useAsDefault:true }, { path:'/login', component:LoginComponent, name:'Login' }, { path:'/feed', component:FeedComponent, name:'Feed' } ]) export class AppComponent { title = 'My App'; constructor( private _r:Router ){} } 

假设你想添加CSS到我的活动状态/选项卡。 使用routerLinkActive激活您的路由链接。

注意:“主动”是我的class级名称

 <style> .active{ color:blue; } </style> <a routerLink="/home" [routerLinkActive]="['active']">Home</a> <a routerLink="/about" [routerLinkActive]="['active']">About</a> <a routerLink="/contact" [routerLinkActive]="['active']">Contact</a> 

我正在使用angular度路由器^3.4.7 ,我仍然有routerLinkActive指令的问题。

如果你有多个链接使用相同的url加上它不会一直刷新,这是行不通的。

受@tomaszbak答复的启发,我创build了一个小组件来完成这项工作