Angular 16迁移后用inject()实现守卫时出现NullInjectorError
Angular 16迁移:CanActivate守卫NullInjectorError问题解决
在Angular 16迁移过程中,弃用原有的CanActivate类守卫,改用函数式守卫+inject()方法后,导航时抛出NullInjectorError: No provider for At!错误,尝试直接在路由配置中使用箭头函数、定义独立CanActivateFn均未解决。
1. 修正函数式守卫的写法
确保inject()在注入上下文内调用,即放在CanActivateFn函数体内,而非路由配置的顶层。
完整守卫代码(my.guard.ts):
import { Injectable } from '@angular/core'; import { CanActivateFn, inject } from '@angular/router'; @Injectable({ providedIn: 'root' }) export class MyGuard { // 若存在其他依赖(如AuthService),需确保依赖服务已正确提供 // constructor(private authService: AuthService) {} canActivate(): boolean { return true; // 此处编写动态判断逻辑 } } // 定义独立的函数式守卫 export const MyGuardFn: CanActivateFn = () => { // 仅在守卫执行时才注入MyGuard,确保处于注入上下文 return inject(MyGuard).canActivate(); };
路由配置代码:
import { NgModule } from '@angular/core'; import { RouterModule, Routes } from '@angular/router'; import { ContainerComponent } from './container.component'; import { MyGuardFn } from './my.guard'; const routes: Routes = [ { path: '', component: ContainerComponent, // 直接引用定义好的函数式守卫 canActivate: [MyGuardFn] } ]; @NgModule({ imports: [RouterModule.forChild(routes)], exports: [RouterModule] }) export class RoutingModule {}
2. 排查核心问题:未提供的依赖服务
错误信息中的At是混淆后的服务名,需定位真实依赖:
- 关闭生产模式混淆,执行
ng serve或ng build --configuration development,此时错误会显示真实的服务类名; - 检查该服务是否添加了
@Injectable({ providedIn: 'root' }),或在对应模块的providers数组中声明; - 排除循环依赖:若
MyGuard和依赖服务互相注入,需重构代码解除循环。
3. 额外注意事项
- 避免在路由配置数组的顶层直接调用
inject():路由数组初始化时注入上下文尚未就绪,可能导致注入失败; - 确保类名正确:原代码中
RoutingModuleComponent命名不合理,路由模块类应命名为RoutingModule(无Component后缀)。
内容的提问来源于stack exchange,提问作者Rahul Roy
相关产品推荐
相关产品推荐

