Angular 9 - onSameUrlNavigation='reload' 不触发路由器事件



我的 Angular 9 应用程序有一个 CustomErrorHandler 和一个 ErrorPageComponent。当整个应用中抛出任何异常时,CustomErrorHandler 将告诉路由器导航到 ErrorPageComponent。但是,ErrorPageComponent中有一个按钮可以抛出自己的异常,在这种情况下,我希望CustomErrorHandler仍然告诉路由器导航到ErrorPageComponent,这是正常的。但是,当 ErrorPageComponent 以这种方式路由到自身时,它需要再次调用其初始化方法。

通常,如果您希望组件在路由到自身后调用初始化方法,则只需订阅路由事件即可。然后,只要您正确地将 onSameUrlNavigation 设置为重新加载,当组件导航到自身时,路由器将触发路由事件将调用您的组件用于订阅它的任何回调方法。

但是,当我的 CustomErrorHandler 告诉路由器导航到 ErrorPageComponent 时,不会触发路由事件。

如果您查看代码,这将更有意义:

这是我在app-routing.module.ts中的路由配置:

const routes: Routes = [
{ path: 'normal', component: NormalComponent},
{ path: '',   redirectTo: '/normal', pathMatch: 'full'}
];
const volitileRoutes: Routes = [
{ path: 'error', component: ErrorPageComponent}
];
const fallbackRoute: Routes = [
{ path: '**', component: Error404PageComponent }
];
@NgModule({
imports: [
RouterModule.forRoot(routes),
RouterModule.forRoot(volitileRoutes, {onSameUrlNavigation: 'reload'}), // I've correctly set onSameUrlNavigation
RouterModule.forRoot(fallbackRoute)
],
exports: [RouterModule]
})
export class AppRoutingModule { }

下面是 CustomErrorHandler,它将重定向到 ErrorPageComponent:

@Injectable({
providedIn: 'root'
})
export class CustomErrorHandler extends ErrorHandler {
constructor(private ngZone: NgZone, private router: Router){
super();
}
handleError(error: any){
// error handling code here
console.log('error caught'); // I've confirmed that my CustomErrorHandler is in fact handling errors.
/* This is not the normal way to do navigation. But for reasons I don't understand, this
is the only way to get navigation to work from within an ErrorHandler; you cannot simply
call router.navigate like normal from within an ErrorHandler. */
this.ngZone.run(() => this.router.navigate(['/error']));
}
}

最后,这里是ErrorPageComponent:

@Component({
selector: 'app-error-page',
templateUrl: './error-page.component.html',
styleUrls: ['./error-page.component.css']
})
export class ErrorPageComponent implements OnInit, OnDestroy {
private navSubscription = new Subscription();
constructor(private router: Router) { }
ngOnInit(): void {
this.navSubscription = this.router.events.subscribe((e: any) => {
console.log('route event triggered'); // this line is never reached
if (e instanceof NavigationEnd) {
// do initialization code
}
});
}
ngOnDestroy(): void {
this.navSubscription?.unsubscribe(); // this prevents a memory leak
}
}

正如我在代码注释中提到的,我已经确认 CustomErrorHandler 正在正确处理错误,并且正在调用路由器导航方法。但是,永远不会调用传递给路由器导航事件的订阅回调方法。我做错了什么?如何在错误页面组件中订阅路由事件?

您是否尝试先重定向到虚拟位置,然后重定向到实际组件,

this.router.navigateByUrl('/', {skipLocationChange: true}).then(()=>
this.router.navigate(['/error'])
);

我建议您将第一个位置设置为具有ngOnInit和ngOnDestroy的位置,这些位置不会执行很多操作,因为这将在路由到新位置之前等待初始化和销毁。

这样做你不需要使用onSameUrlNavigation,我认为它更好,因为你不需要使用订阅,所以销毁它,你不必设置onSameUrlNavigation你可以简单地重新加载当你想要一个简单的功能。

但是,如果要使用订阅,请将其移动到构造函数中,而不是在ngOnInit函数中。

最新更新