Angular 15中Web Shell模块注入特性路由及NG0203错误解决
解决Angular NG0203错误及动态路由配置问题
错误原因
- 在
@NgModule的imports数组中直接调用inject(APP_ROUTES),此时代码不在Angular的注入上下文(构造函数、工厂函数等)中,触发NG0203错误。 APP_ROUTES的provider存在循环依赖(deps中包含自身),导致注入逻辑失效。
解决方案一(推荐,使用Angular 15+独立API)
利用provideRouter替代RouterModule.forRoot,它支持在路由配置函数中安全使用inject()获取依赖:
import { inject, InjectionToken, NgModule } from '@angular/core'; import { Routes, provideRouter, RouterModule, LoadChildrenCallback } from '@angular/router'; import { HOME_PAGE } from '@my-org/shared/auth-login/data-access/store'; export const LOAD_FEATURE_ROUTES = new InjectionToken<LoadChildrenCallback>('LOAD_FEATURE_ROUTES'); function createRoutes(): Routes { const homePage = inject(HOME_PAGE); const childRoutes = inject(LOAD_FEATURE_ROUTES); return [ { path: 'auth', loadChildren: async () => (await import('./auth-routes')).AUTH_ROUTES, }, { path: homePage, loadChildren: childRoutes }, { path: '', redirectTo: 'auth', pathMatch: 'full' }, { path: '**', redirectTo: 'auth' }, ]; } @NgModule({ imports: [RouterModule], providers: [ provideRouter(createRoutes(), { scrollPositionRestoration: 'top', }) ], exports: [RouterModule], }) export class SharedAuthLoginRoutingModule { }
关键改动说明
- 移除冗余的
APP_ROUTEStoken,直接通过createRoutes生成带注入配置的路由 provideRouter会在注入上下文内执行createRoutes,允许安全使用inject()获取应用提供的HOME_PAGE和LOAD_FEATURE_ROUTES- 保留
RouterModule的导入和导出,确保与现有NgModule生态兼容
应用侧配置无需改变,依然通过providers提供所需token:
providers: [ { provide: HOME_PAGE, useValue: 'my-app-homepage', }, { provide: LOAD_FEATURE_ROUTES, useValue: async () => (await import('./feature-routes')).FEATURE_ROUTES }, ],
解决方案二(兼容传统RouterModule.forRoot方式)
如果不想使用独立API,可以通过APP_INITIALIZER在应用启动时动态设置路由:
import { inject, InjectionToken, NgModule, APP_INITIALIZER } from '@angular/core'; import { Routes, Router, RouterModule, LoadChildrenCallback } from '@angular/router'; import { HOME_PAGE } from '@my-org/shared/auth-login/data-access/store'; export const LOAD_FEATURE_ROUTES = new InjectionToken<LoadChildrenCallback>('LOAD_FEATURE_ROUTES'); function initRoutes(router: Router, homePage: string, childRoutes: LoadChildrenCallback) { return () => { router.resetConfig([ { path: 'auth', loadChildren: async () => (await import('./auth-routes')).AUTH_ROUTES, }, { path: homePage, loadChildren: childRoutes }, { path: '', redirectTo: 'auth', pathMatch: 'full' }, { path: '**', redirectTo: 'auth' }, ]); }; } @NgModule({ imports: [RouterModule.forRoot([], { scrollPositionRestoration: 'top', })], providers: [ { provide: APP_INITIALIZER, useFactory: initRoutes, deps: [Router, HOME_PAGE, LOAD_FEATURE_ROUTES], multi: true } ], exports: [RouterModule], }) export class SharedAuthLoginRoutingModule { }
关键改动说明
- 用
RouterModule.forRoot初始化空路由配置 - 通过
APP_INITIALIZER在应用启动阶段,利用Router.resetConfig动态替换为注入了应用配置的路由 APP_INITIALIZER的工厂函数处于注入上下文内,可安全获取所需依赖
内容的提问来源于stack exchange,提问作者Andrew Allen
相关产品推荐
相关产品推荐

