You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 08:53:33