Angular13 Resolver注入Router后调用navigate报undefined错误如何解决
核心错误原因
你报错Cannot read properties of undefined (reading 'navigate')和Router注入无关,是回调函数的this指向丢失导致的:
你在subscribe里直接传递了this.resolveSuccess和this.resolveError作为回调,当这两个函数被异步调用时,内部的this不再指向WordpressResolver类的实例,所以this.router就是undefined。
修复方案
三种方案选一种即可:
方案1:用箭头函数包裹回调(最常用)
箭头函数会继承外层作用域的this指向,修改subscribe部分的代码:
this.http .get<UrlData>(environment.domain + state.url) .subscribe( (res) => this.resolveSuccess(res), (err) => this.resolveError(err) );
方案2:用bind方法绑定this
手动绑定回调的this指向类实例:
this.http .get<UrlData>(environment.domain + state.url) .subscribe( this.resolveSuccess.bind(this), this.resolveError.bind(this) );
方案3:直接把回调方法定义为箭头函数
修改类内的方法定义,从普通函数改为箭头函数:
private resolveSuccess = (urlData: UrlData): void => { // 原有逻辑不变 } private resolveError = (error: HttpErrorResponse): void => { // 原有逻辑不变 }
额外优化建议
你的Resolver当前用法不符合Angular规范,建议同步调整:
- Resolver如果处理异步逻辑,需要返回Observable/Promise,你现在直接同步返回
this.error,会导致HTTP请求还没返回,路由就已经完成resolve流程加载了NotFoundComponent,后续的navigate属于路由完成后的二次跳转,体验很差。 - 你已经给Resolver加了
providedIn: 'root',就不需要再在AppRoutingModule的providers里重复声明了,重复声明可能会导致生成多实例。
优化后的resolve方法示例:
resolve( route: ActivatedRouteSnapshot, state: RouterStateSnapshot ): Observable<HttpErrorResponse | null> { return this.http .get<UrlData>(environment.domain + state.url) .pipe( tap(urlData => { switch (urlData.type) { case UrlType.POSTS: this.router.navigate(['/posts'], { skipLocationChange: false }); break; case UrlType.POST: this.router.navigate(['/post', urlData.id], { skipLocationChange: false }); break; case UrlType.PAGE: this.router.navigate(['/page', urlData.id], { skipLocationChange: false }); break; } }), map(() => null), catchError((error: HttpErrorResponse) => { this.router.navigate(['/error'], { skipLocationChange: true }); return of(error); }) ) }
内容的提问来源于stack exchange,提问作者Morysh
相关产品推荐
相关产品推荐

