Angular:如何在CanActivateFn中注入Router并使用runInInjectionContext
解决Angular CanActivateFn异步场景下的注入问题
在Angular的函数式守卫CanActivateFn中,若在await异步操作后调用inject()会抛出错误——这是因为inject()必须在注入上下文的同步执行阶段调用,异步操作会脱离原注入上下文。要解决这个问题,你可以通过runInInjectionContext方法在异步回调中重新获取注入上下文,从而正常使用Router等服务。
修正后的守卫代码
import { CanActivateFn, inject, runInInjectionContext, Injector } from '@angular/core'; import { Router } from '@angular/router'; export const otapGuard: CanActivateFn = async (route, state) => { // 在await前先获取Injector实例(此时仍处于注入上下文) const injector = inject(Injector); const APPID = chrome.runtime.id; // 执行异步操作 const { omgeving } = await chrome.storage.local.get('omgeving'); if (omgeving === getAppEnvironment(APPID)) { return true; } // 使用runInInjectionContext包裹需要注入服务的逻辑 return runInInjectionContext(injector, () => { return inject(Router).createUrlTree([]); // 替换为你的目标路由路径 }); };
关键说明
- 必须在
await之前调用inject(Injector):此时守卫函数刚执行,仍处于Angular的注入上下文范围内,能正常获取Injector实例。 runInInjectionContext接收两个参数:Injector实例,以及需要在注入上下文中执行的回调函数。在回调内部可以安全使用inject()获取任意Angular服务。- 最终返回值符合
CanActivateFn要求的类型:boolean | UrlTree | Observable<boolean | UrlTree> | Promise<boolean | UrlTree>,返回UrlTree即可触发重定向。
路由配置无需修改
你的原有路由配置可以保持不变:
{ path: 'popup', loadChildren: () => import('./popup/popup.module').then(m => m.PopupModule), resolve: { user: TokenResolver }, canActivate: [OtapGuard, MyMsalGuard] },
内容的提问来源于stack exchange,提问作者YhEtesian
相关产品推荐
相关产品推荐

