如何检测Angular 2中的路由更改?

我正在寻找检测我的App.ts文件中的路线更改。

此后,我将检查全局用户令牌以查看他是否已登录。如果用户未登录,则可以重定向用户。

在Angular 2中,您可以subscribe (Rx事件)到一个路由器实例。 所以你可以做一些事情

 class MyClass { constructor(private router: Router) { router.subscribe((val) => /*whatever*/) } } 

编辑 (自rc.1)

 class MyClass { constructor(private router: Router) { router.changes.subscribe((val) => /*whatever*/) } } 

编辑2 (自2.0.0起)

另请参阅: Router.events文档

 class MyClass { constructor(private router: Router) { router.events.subscribe((val) => { // see also console.log(val instanceof NavigationEnd) }); } } 

新路由器> = RC.3

 import { Router, NavigationStart, NavigationEnd, NavigationError, NavigationCancel, RoutesRecognized } from '@angular/router'; constructor(router:Router) { router.events.forEach((event) => { if(event instanceof NavigationStart) { } // NavigationEnd // NavigationCancel // NavigationError // RoutesRecognized }); } 

您也可以按给定的事件过滤:

 import 'rxjs/add/operator/filter'; constructor(router:Router) { router.events .filter(event => event instanceof NavigationStart) .subscribe((event:NavigationStart) => { // You only receive NavigationStart events }); } 

使用pairwise运算符来获得以前和当前的事件也是一个不错的主意。 https://github.com/angular/angular/issues/11268#issuecomment-244601977

 import 'rxjs/add/operator/pairwise'; import { Router } from '@angular/router; export class AppComponent { constructor(private router: Router) { this.router.events.pairwise().subscribe((event) => { console.log(event); }); }; } 

路由器3.0.0-beta.2应该是

 this.router.events.subscribe(path => { console.log('path = ', path); }); 

这里的答案是正确的router-deprecated 。 对于最新版本的router

 this.router.changes.forEach(() => { // Do whatever in here }); 

要么

 this.router.changes.subscribe(() => { // Do whatever in here }); 

要查看两者之间的差异,请查看这个SO问题 。

编辑

对于最新的你必须做的:

 this.router.events.subscribe(event: Event => { // Handle route change }); 

以下的一些作品,可能会为你做些棘手的事情。

 // in constructor of your app.ts with router and auth services injected router.subscribe(path => { if (!authService.isAuthorised(path)) //whatever your auth service needs router.navigate(['/Login']); }); 

不幸的是,这个重定向稍后在路由过程中比我想要的。 原始目标组件的onActivate()在重定向之前调用。

有一个@CanActivate装饰器可以在目标组件上使用,但这是a)不集中,b)不能从注入的服务中受益。

如果有人能提出一个更好的途径来集中授权一条路线,那将是非常好的。 我相信肯定有更好的办法。

这是我现在的代码(我将如何改变它来听路由改变?):

 import {Component, View, bootstrap, bind, provide} from 'angular2/angular2'; import {ROUTER_BINDINGS, RouterOutlet, RouteConfig, RouterLink, ROUTER_PROVIDERS, APP_BASE_HREF} from 'angular2/router'; import {Location, LocationStrategy, HashLocationStrategy} from 'angular2/router'; import { Todo } from './components/todo/todo'; import { About } from './components/about/about'; @Component({ selector: 'app' }) @View({ template: ` <div class="container"> <nav> <ul> <li><a [router-link]="['/Home']">Todo</a></li> <li><a [router-link]="['/About']">About</a></li> </ul> </nav> <router-outlet></router-outlet> </div> `, directives: [RouterOutlet, RouterLink] }) @RouteConfig([ { path: '/', redirectTo: '/home' }, { path: '/home', component: Todo, as: 'Home' }, { path: '/about', component: About, as: 'About' } ]) class AppComponent { constructor(location: Location){ location.go('/'); } } bootstrap(AppComponent, [ROUTER_PROVIDERS, provide(APP_BASE_HREF, {useValue: '/'})]); 

@卢多恩回答很好,但是如果你不想用instanceof使用下面的话

 this.router.events.subscribe(event => { if(event.constructor.name === "NavigationStart") { // do something... } }); 

用这种方法你可以检查当前的事件名称作为一个字符串,如果事件发生,你可以做你计划你的功能做。

以下列方式捕获路由更改事件…

 import { Component, OnInit, Output, ViewChild } from "@angular/core"; import { Router, NavigationStart, NavigationEnd, Event as NavigationEvent } from '@angular/router'; @Component({ selector: "my-app", templateUrl: "app/app.component.html", styleUrls: ["app/app.component.css"] }) export class AppComponent { constructor(private cacheComponentObj: CacheComponent, private router: Router) { /* Route event types NavigationEnd NavigationCancel NavigationError RoutesRecognized */ router.events.forEach((event: NavigationEvent) => { //Before Navigation if (event instanceof NavigationStart) { switch (event.url) { case "/app/home": { //Do Work break; } case "/app/About": { //Do Work break; } } } //After Navigation if (event instanceof NavigationEnd) { switch (event.url) { case "/app/home": { //Do Work break; } case "/app/About": { //Do Work break; } } } }); } } 

我从RC 5开始就这样做

 this.router.events .map( event => event instanceof NavigationStart ) .subscribe( () => { // TODO } ); 

Angular 4.x及以上版本:

这可以通过使用ActivatedRoute类的url属性来实现,如下所示,

 this.activatedRoute.url.subscribe(url =>{ console.log(url); }); 

注意:您需要从angular/router包导入并注入提供程序

 import { ActivatedRoute } from '@angular/router` 

 constructor(private activatedRoute : ActivatedRoute){ } 
Interesting Posts