Angular服务中路由触发非NgZone警告及返回值需求解决办法
解决Angular Service中路由导航的Zone警告问题
问题分析
警告Navigation triggered outside Angular zone, did you forget to call 'ngZone.run()'?是因为路由导航操作发生在Angular变更检测Zone之外,而常规的ngZone.run()无返回值写法会丢失router.navigate()返回的Promise,导致无法监听导航完成事件。
解决方案
利用NgZone.run()可接收并返回Promise的特性,将router.navigate()包裹在ngZone.run()内部,同时保留Promise到Observable的转换,既让导航回到Angular Zone内,又能继续监听导航状态。
步骤1:注入NgZone
确保在Service的构造函数中注入NgZone:
constructor( private router: Router, private route: ActivatedRoute, private ngZone: NgZone // 注入NgZone ) {}
步骤2:修改路由处理方法
调整handleRedirectRouting方法,将router.navigate()放在ngZone.run()中:
private handleRedirectRouting(): Observable<boolean> { return this.route.queryParamMap.pipe( switchMap((params) => { if (params.get('_redirect')) { const route = params.get('_redirect'); // 将navigate包裹在ngZone.run内,run会返回navigate的Promise return from(this.ngZone.run(() => this.router.navigate([route]))); } else if (this.router.url.includes('auth/login')) { const route = '/'; return from(this.ngZone.run(() => this.router.navigate([route]))); } return of(true); }) ); }
原理说明
NgZone.run()支持传入有返回值的函数,当函数返回Promise时,run()会直接返回该Promise。通过from()操作符将其转换为Observable后,既解决了Zone外导航的警告,又能继续监听导航完成的状态(Observable的布尔值对应导航成功/失败)。
内容的提问来源于stack exchange,提问作者btx
相关产品推荐
相关产品推荐

