在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
对象,并返回true
或false
无论该指令对于当前路由是否成立。 您可以使用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,以查看哪个路由处于活动状态。 请注意,无论您使用的是哪种LocationStrategy
, Location
类都会返回规范化的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
不再定义isRouteActive
并generate
方法。
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了一个小组件来完成这项工作