首页 > 解决方案 > 无法将 `Route` 和 `ActivatedRouteSnapshot` 注入 `HttpInterceptor`

问题描述

代码的简化版本:

@Injectable()
export class JwtInterceptor implements HttpInterceptor {
  constructor(
    private readonly router: Router,
    private readonly activatedRouteSnapshot: ActivatedRouteSnapshot,
    @Inject(AuthServiceFactory) private readonly authServiceFactory: ServiceFactoryBase<IAuthService>,
    @Inject(LoggingServiceFactory) private readonly loggingServiceFactory: ServiceFactoryBase<ILoggingService>) {
    console.log('router', router);
    console.log('activated-route-snapshot', activatedRouteSnapshot);
  }

这些都无法解决。它失败并显示以下标准消息:

StaticInjectorError(AppModule)[InjectionToken HTTP_INTERCEPTORS -> ActivatedRouteSnapshot]:StaticInjectorError(平台:核心)[InjectionToken HTTP_INTERCEPTORS -> ActivatedRouteSnapshot]:NullInjectorError:没有ActivatedRouteSnapshot的提供者!

RouterModule..导入应用程序的正确方法是什么?

PS我得到SharedModule而不是AppModule导出所有的东西,但不是Angular的:

@NgModule({
    declarations: any.concat(pipes),
    providers: any
        .concat(serviceFactories)
        .concat(guards)
        .concat(otherProviders)
        .concat([{
            provide: HTTP_INTERCEPTORS,
            useClass: JwtInterceptor,
            multi: true
        }]),
    exports: any.concat(pipes)
})
export class SharedModule {
    static forRoot(): ModuleWithProviders {
        return {
            ngModule: SharedModule,
            providers: any
                .concat(serviceFactories)
                .concat(guards)
                .concat(otherProviders)
        };
    }
}

AppModule

@NgModule({
  declarations: appComponents.concat(auxComponents),
  imports: [
    // theirs
    BrowserModule,
    HttpClientModule,
    AppRoutingModule,

    // ours
    SharedModule,
    CoursesModule
  ],
  bootstrap: [
    AppComponent
  ]
})
export class AppModule { }

标签: angularangular-routerangular-dependency-injection

解决方案


当你必须使用 a 时ClassProviderHttpInterceptorAngular 不能像编译作为令牌本身包含在模块中的提供者那样编译提供者依赖项。基本上,类型标记在运行时并不真正存在,Angular 使用这些标记进行依赖注入——因为 aClassProvider或 aValueProvider是在运行时评估的,所以它们没有得到应有的正确 DI 处理。

你只需要对它进行更多的声明:

    {
        provide: HTTP_INTERCEPTORS,
        useClass: JwtInterceptor,
        deps: [Router, ActivatedRoute],
        multi: true
    }

数组中的令牌deps将在创建时注入到组件中。这里的一件挑剔的事情是它们deps必须与它们在构造函数参数中的顺序相同。

此外, anActivatedRouteSnapshot的提供者只是ActivatedRoute.

你应该能够通过使用@Inject()装饰器来完成同样的事情,就像你对其他提供者所做的那样——Angular 将在第一个匹配项的依赖关系树上进行并注入它(尽管我对此不是 100% 确定)。


推荐阅读