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

Angular 9 - onSameUrlNavigation='reload' not triggering router event

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

通常情况下,如果你想让一个组件在路由到它自己之后调用一个初始化方法,你可以简单地订阅路由事件。然后,只要你正确设置了onSameUrlNavigation重新加载,当组件导航到自己时,路由器会触发一个路由事件,调用你的组件订阅它的回调方法。

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

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

这是我在应用程序中的路由配置-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 { }

这是将重定向到 ErrorPageComponent 的 CustomErrorHandler:

@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 正在正确处理错误,并且正在调用路由器导航方法。但是,永远不会调用传递给路由器导航事件的订阅回调方法。我究竟做错了什么?如何订阅 ErrorPageComponent 中的路由事件?

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

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

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

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

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