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

Angular自定义Router类时触发NullInjectionError问题求助

问题:重写Angular Router的navigate方法时触发NullInjectorError

我需要重写Router类的navigate(commands: any[], extras?: NavigationExtras): Promise<boolean>方法,确保NavigationExtras中的queryParamsHandling始终为preserve。

实现的自定义Router类

@Injectable({
    providedIn: 'root'
})
export class MmosRouter extends Router {

    constructor(
        rootComponentType: Type<any>,
        urlSerializer: UrlSerializer,
        contexts: ChildrenOutletContexts,
        location: Location_2,
        injector: Injector,
        compiler: Compiler,
        @Inject(ROUTES) config: Route[][]
    ) {
        super(rootComponentType, urlSerializer, contexts, location, injector, compiler, flatten(config));
    }

    navigate(commands: any[], extras?: NavigationExtras): Promise<boolean> {
        extras = { ...extras, queryParamsHandling: 'preserve' };
        return super.navigate(commands, extras);
    }
}

AppModule中的配置

@NgModule({
  declarations: [
    ...
  ],
  imports: [
    ...
  ],
  providers: [
    ...
  {
    provide: Router,
    useFactory: (rootComponentType: Type<any>, urlSerializer: UrlSerializer, contexts: ChildrenOutletContexts, location: Location_2, injector: Injector, config: Route[][]) => {
      return new MmosRouter(rootComponentType, urlSerializer, contexts, location, injector, config);
    },
    deps: [ApplicationRef, UrlSerializer, ChildrenOutletContexts, Location_2, Injector, Compiler, ROUTES]
  },
    ...
  ],
  bootstrap: [...],
  exports: [
    ...
  ],
})
export class AppModule {
  constructor(service: ApmService) {}
}

报错信息

core.mjs:9171 ERROR NullInjectorError: R3InjectorError(AppModule)[MmosRouter -> Function -> Function -> Function]: 
NullInjectorError: No provider for Function!
  at NullInjector.get (core.mjs:8191:27)
  at R3Injector.get (core.mjs:8618:33)
  at R3Injector.get (core.mjs:8618:33)
  at R3Injector.get (core.mjs:8618:33)
  at injectInjectorOnly (core.mjs:4782:33)
  at Module.ɵɵinject (core.mjs:4786:12)
  at Object.MmosRouter_Factory [as factory] (mmosRouter.ts:17:24)
  at R3Injector.hydrate (core.mjs:8719:35)
  at R3Injector.get (core.mjs:8607:33)
  at ChainedInjector.get (core.mjs:13811:36)

(报错指向MmosRouter类的定义行)

解决方案

1. 移除MmosRouter上的@Injectable装饰器

因为我们通过useFactory提供Router实例,不需要Angular自动尝试实例化MmosRouter,移除后避免注入冲突:

export class MmosRouter extends Router {
    // 构造函数和navigate方法保持不变
}

2. 修正useFactory的参数与依赖匹配

原useFactory缺少Compiler参数,导致传递给MmosRouter的参数顺序错误,同时确保导入flatten函数:

// 导入必要依赖
import { flatten, Route, Router, ROUTES, UrlSerializer, ChildrenOutletContexts } from '@angular/router';
import { Location } from '@angular/common';
import { Compiler, Injector, Type, ApplicationRef } from '@angular/core';

// AppModule的providers配置
{
    provide: Router,
    useFactory: (
        rootComponentType: Type<any>,
        urlSerializer: UrlSerializer,
        contexts: ChildrenOutletContexts,
        location: Location,
        injector: Injector,
        compiler: Compiler,
        @Inject(ROUTES) config: Route[][]
    ) => {
        return new MmosRouter(rootComponentType, urlSerializer, contexts, location, injector, compiler, config);
    },
    deps: [ApplicationRef, UrlSerializer, ChildrenOutletContexts, Location, Injector, Compiler, ROUTES]
},

3. 修正Location的导入别名

确保Location从@angular/common直接导入,不要使用Location_2这类别名,避免类型不匹配。

错误原因说明

  • @Injectable({providedIn: 'root'})会让Angular自动创建MmosRouter实例,但它的构造函数依赖的特殊服务无法被正确注入,引发错误。
  • useFactory的参数列表与deps数组顺序不匹配,缺少Compiler参数,导致传递给MmosRouter的参数错误,触发注入异常。

内容的提问来源于stack exchange,提问作者basti394

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 19:10:31