我希望在 AppComponent 中检测路线变化 .
AppComponent
此后,我将检查全局用户令牌以查看他是否已登录 . 然后,如果用户未登录,我可以重定向用户 .
这里的答案对于router-deprecated是正确的 . 对于router的最新版本:
this.router.changes.forEach(() => { // Do whatever in here });
要么
this.router.changes.subscribe(() => { // Do whatever in here });
要查看两者之间的差异,请查看this SO question .
Edit
最新的你必须做的:
this.router.events.subscribe(event: Event => { // Handle route change });
RxJS 6
router.events.pipe(filter(event => event instanceof NavigationStart))
感谢Peilonrayz(见下面的评论)
new router >= 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 operator获取上一个和当前事件也是一个不错的主意 . https://github.com/angular/angular/issues/11268#issuecomment-244601977
import'rxjs / add / operator / pairwise';从'@ angular / router导入;
export class AppComponent {构造函数(私有路由器:路由器){this.router.events.pairwise() . subscribe((event)=> {的console.log(事件);});};}
@Ludohen 答案很棒,但如果您不想使用 instanceof 请使用以下内容
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; } } } }); } }
Angular 6,如果你想 subscribe 到 router
subscribe
router
import { Router, NavigationEnd } from '@angular/router'; import { filter } from 'rxjs/operators'; constructor( private router: Router ) { router.events.pipe( filter(event => event instanceof NavigationEnd) ).subscribe((event: NavigationEnd) => { console.log(event.url); }); }
Angular 4.x及以上:
这可以使用ActivatedRoute类的url属性实现,如下所示,
this.activatedRoute.url.subscribe(url =>{ console.log(url); });
Note: 您需要从 angular/router 包导入并注入提供程序
angular/router
import { ActivatedRoute } from '@angular/router`
和
constructor(private activatedRoute : ActivatedRoute){ }
RC 5之后我这样做了
this.router.events .map( event => event instanceof NavigationStart ) .subscribe( () => { // TODO } );
以下KIND的作品可能对您来说很棘手 .
// 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() .
onActivate()
您可以在目标组件上使用 @CanActivate 装饰器,但这是a)非集中式,b)不会从注入的服务中受益 .
@CanActivate
如果有人能够在提交之前建议更好的集中授权方式,那将会很棒 . 我相信一定有更好的方法 .
这是我当前的代码(如何更改它以侦听路由更改?):
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: '/'})]);
只需对AppRoutingModule进行更改即可
@NgModule({ imports: [RouterModule.forRoot(routes, { scrollPositionRestoration: 'enabled' })], exports: [RouterModule] })
在Angular 2中,您可以 subscribe (Rx事件)到Router实例 . 所以你可以做的事情
class MyClass { constructor(private router: Router) { router.subscribe((val) => /*whatever*/) } }
Edit (自rc.1起)
class MyClass { constructor(private router: Router) { router.changes.subscribe((val) => /*whatever*/) } }
Edit 2 (自2.0.0起)
另见:Router.events doc
class MyClass { constructor(private router: Router) { router.events.subscribe((val) => { // see also console.log(val instanceof NavigationEnd) }); } }
路由器3.0.0-beta.2应该是
this.router.events.subscribe(path => { console.log('path = ', path); });
import { Component } from '@angular/core'; import { Router, Event, NavigationStart, NavigationEnd, NavigationError } from '@angular/router'; @Component({ selector: 'app-root', template: `<router-outlet></router-outlet>` }) export class AppComponent { constructor(private router: Router) { this.router.events.subscribe((event: Event) => { if (event instanceof NavigationStart) { // Show loading indicator } if (event instanceof NavigationEnd) { // Hide loading indicator } if (event instanceof NavigationError) { // Hide loading indicator // Present error to user console.log(event.error); } }); } }
在角度6和RxJS6中:
import { filter, debounceTime } from 'rxjs/operators'; this.router.events.pipe( filter((event) => event instanceof NavigationEnd), debounceTime(40000) ).subscribe( x => { console.log('val',x); this.router.navigate(['/']); /*Redirect to Home*/ } )
我正在使用angular5应用程序,我面临同样的问题 . 当我浏览Angular文档时,他们提供了处理路由器事件的最佳解决方案 . 请查看以下文档 .
Angular中的路由器事件Route events in angular5
但特别针对有问题的案例我们需要 NavigationEnd Event
Navigation End Event Angular
表示导航成功结束时触发的事件
How to use this ?
import { Component, OnInit } from '@angular/core'; import { Router, ActivatedRouteSnapshot, NavigationEnd } from '@angular/router'; @Component({ selector: 'app-navbar', templateUrl: './navbar.component.html', styleUrls: ['./navbar.component.css'] }) export class NavbarComponent implements OnInit { constructor(private router: Router) { } ngOnInit(): void { //calls this method when navigation ends this.router.events.subscribe(event => { if (event instanceof NavigationEnd) { //calls this stuff when navigation ends console.log("Event generated"); } }); } }
When to use this ?
在我的情况下,我的应用程序为所有用户(例如用户,管理员)共享公共仪表板,但我需要根据用户类型显示和隐藏一些导航栏选项 .
这就是为什么每当url更改时我需要调用服务方法,该方法根据响应返回登录的用户信息,我将进行进一步的操作 .
以上大多数解决方案都是正确的,但是我面临的问题就是多次发出“导出发射”事件 . 当我更改任何路线时,会触发此事件 . 所以听到Angular 6的完整解决方案 .
import { Subscription } from 'rxjs/Subscription'; import 'rxjs/add/operator/do'; import 'rxjs/add/operator/filter'; export class FooComponent implements OnInit, OnDestroy { private _routerSub = Subscription.EMPTY; constructor(private router: Router){} ngOnInit(){ this._routerSub = this.router.events .filter(event => event instanceof NavigationEnd) .subscribe((value) => { //do something with the value }); } ngOnDestroy(){ this._routerSub.unsubscribe(); } }
15 回答
这里的答案对于router-deprecated是正确的 . 对于router的最新版本:
要么
要查看两者之间的差异,请查看this SO question .
Edit
最新的你必须做的:
RxJS 6
感谢Peilonrayz(见下面的评论)
new router >= RC.3
您还可以按给定的事件进行过滤:
使用pairwise operator获取上一个和当前事件也是一个不错的主意 . https://github.com/angular/angular/issues/11268#issuecomment-244601977
export class AppComponent {
构造函数(私有路由器:路由器){
this.router.events.pairwise() . subscribe((event)=> {
的console.log(事件);
});
};
}
@Ludohen 答案很棒,但如果您不想使用
instanceof
请使用以下内容通过这种方式,您可以将当前事件名称检查为字符串,如果事件发生,您可以执行您计划的功能 .
Angular 6,如果你想
subscribe
到router
Angular 4.x及以上:
这可以使用ActivatedRoute类的url属性实现,如下所示,
Note: 您需要从
angular/router
包导入并注入提供程序和
RC 5之后我这样做了
以下KIND的作品可能对您来说很棘手 .
不幸的是,这会在路由过程中重定向,而不是我想要的 . 在重定向之前调用原始目标组件的
onActivate()
.您可以在目标组件上使用
@CanActivate
装饰器,但这是a)非集中式,b)不会从注入的服务中受益 .如果有人能够在提交之前建议更好的集中授权方式,那将会很棒 . 我相信一定有更好的方法 .
这是我当前的代码(如何更改它以侦听路由更改?):
只需对AppRoutingModule进行更改即可
在Angular 2中,您可以
subscribe
(Rx事件)到Router实例 . 所以你可以做的事情Edit (自rc.1起)
Edit 2 (自2.0.0起)
另见:Router.events doc
路由器3.0.0-beta.2应该是
在角度6和RxJS6中:
我正在使用angular5应用程序,我面临同样的问题 . 当我浏览Angular文档时,他们提供了处理路由器事件的最佳解决方案 . 请查看以下文档 .
Angular中的路由器事件Route events in angular5
但特别针对有问题的案例我们需要 NavigationEnd Event
Navigation End Event Angular
How to use this ?
When to use this ?
在我的情况下,我的应用程序为所有用户(例如用户,管理员)共享公共仪表板,但我需要根据用户类型显示和隐藏一些导航栏选项 .
这就是为什么每当url更改时我需要调用服务方法,该方法根据响应返回登录的用户信息,我将进行进一步的操作 .
以上大多数解决方案都是正确的,但是我面临的问题就是多次发出“导出发射”事件 . 当我更改任何路线时,会触发此事件 . 所以听到Angular 6的完整解决方案 .