如何检测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){ }