Answers:
在Angular 2中,您可以subscribe
(Rx事件)到Router实例。所以你可以做类似的事情
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)
});
}
}
filter
运算符轻松过滤事件。router.events.pipe(filter(e => e instanceof NavigationEnd).subscribe((e) => { ... }
RxJS 6
router.events.pipe(filter(event => event instanceof NavigationStart))
感谢Peilonrayz(请参阅下面的评论)
新路由器> = 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); }); }; }
Argument of type '(event: Event) => void' is not assignable to parameter of type
Argument of type '(event: Event) => void' is not assignable to parameter of type
错误是因为您在过滤器代码段中预订的是Event类型的对象,而不是NavigationEvent。
对于Angular 7,有人应该这样写:
this.router.events.subscribe((event: Event) => {})
一个详细的示例可以如下所示:
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);
}
});
}
}
角7,如果你要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);
});
注意:
您需要从angular/router
包中导入和注入提供程序
import { ActivatedRoute } from '@angular/router`
和
constructor(private activatedRoute : ActivatedRoute){ }
在angular 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*/
}
)
import {Router, NavigationEnd} from "@angular/router"
这里的答案是正确的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
});
router
已经再次更新(我还没有更新我的答案了),所以我不知道是怎么回事了最新的。对于router
我写的,你不能。@akn
在Angular 8中,您应该喜欢 this.router.events.subscribe((event: Event) => {})
例:
import { Component } from '@angular/core';
import { Router, Event } from '@angular/router';
import { NavigationStart, NavigationError, NavigationEnd } from '@angular/router';
@Component({
selector: 'app-root',
template: `<router-outlet></router-outlet>`
})
export class AppComponent {
constructor(private router: Router) {
//Router subscriber
this.router.events.subscribe((event: Event) => {
if (event instanceof NavigationStart) {
//do something on start activity
}
if (event instanceof NavigationError) {
// Handle error
console.error(event.error);
}
if (event instanceof NavigationEnd) {
//do something on end activity
}
});
}
}
在组件中,您可能想要尝试以下操作:
import {NavigationEnd, NavigationStart, Router} from '@angular/router';
constructor(private router: Router) {
router.events.subscribe(
(event) => {
if (event instanceof NavigationStart)
// start loading pages
if (event instanceof NavigationEnd) {
// end of loading paegs
}
});
}
通过以下方式捕获路线更改事件:
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;
}
}
}
});
}
}
定位工程...
import {Component, OnInit} from '@angular/core';
import {Location} from '@angular/common';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit {
constructor(private location: Location) {
this.location.onUrlChange(x => this.urlChange(x));
}
ngOnInit(): void {}
urlChange(x) {
console.log(x);
}
}
以上大多数解决方案都是正确的,但我遇到的问题是多次发出``导航发出''事件。当我更改任何路线时都会触发此事件。所以听说是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();
}
}
@Ludohen的答案很好,但是如果您不想使用,请instanceof
使用以下内容
this.router.events.subscribe(event => {
if(event.constructor.name === "NavigationStart") {
// do something...
}
});
通过这种方式,您可以将当前事件名称检查为字符串,并且如果发生了事件,则可以执行计划函数的操作。
Event
类型导致Atom中出现错误,这就是为什么我没有使用它的原因
instanceOf
因此您应该使用它,因此您的示例也将在生产代码中工作。if(event instanceOf NavigationStart) {
if(event instanceof NavigationStart)
我正在使用angular5应用程序,并且遇到了相同的问题。当我浏览Angular文档时,它们为处理路由器事件提供了最佳解决方案。请查看以下文档。
Angular中的路由器事件angular5中的路由器事件
但特别是针对有问题的情况,我们需要NavigationEnd事件
表示导航成功结束时触发的事件
如何使用呢?
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");
}
});
}
}
什么时候使用?
就我而言,我的应用程序为所有用户(例如users,Admins)共享通用仪表板,但是我需要根据用户类型显示和隐藏一些导航栏选项。
这就是为什么每当URL更改时我都需要调用service方法,该服务方法将根据响应返回登录的用户信息,我将进行进一步的操作。
以下种类的作品可能会为您带来麻烦。
// 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
你可以在目标组件上使用的装饰,但是这是一个)不集中和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: '/'})]);
只需对AppRoutingModule进行更改即可
@NgModule({
imports: [RouterModule.forRoot(routes, { scrollPositionRestoration: 'enabled' })],
exports: [RouterModule]
})
我会这样写:
ngOnInit() {
this.routed = this.router.events.map( event => event instanceof NavigationStart )
.subscribe(() => {
} );
}
ngOnDestroy() {
this.routed.unsubscribe();
}
event._root.children[0].value._routeConfig.data
希望能够有更好的方法来获取数据