在NGXS状态类中注入InjectionToken时触发Invalid provider错误的解决方法
如何在NGXS State类中注入InjectionToken?
在Angular 18搭配NGXS 18的环境中,尝试在State类中注入InjectionToken时,Angular抛出Error: Invalid provider错误,状态类无法完成初始化,但注入普通服务时一切正常。
相关代码如下:
应用配置代码(app.config.ts)
export interface CustomerConfig { name: string; } export const CUSTOMER_CONFIG = new InjectionToken<CustomerConfig>( 'customer_config' ); export const appConfig: ApplicationConfig = { providers: [ provideZoneChangeDetection({ eventCoalescing: true }), provideRouter(routes), provideStore([ZooState]), { provide: CUSTOMER_CONFIG, useValue: { name: 'Alice', }, }, ], };
ZooState状态类代码
export interface ZooStateModel { favoriteAnimal: string; } export const ZOO_STATE_TOKEN = new StateToken<ZooStateModel>('zoo'); @State<ZooStateModel>({ name: ZOO_STATE_TOKEN, defaults: { favoriteAnimal: 'Unicorn', }, }) @Injectable() export class ZooState { @Selector() static favoriteAnimal(state: ZooStateModel) { return state.favoriteAnimal; } constructor( @Inject(CUSTOMER_CONFIG) private readonly customerConfig: CustomerConfig ) { console.log('Welcome to the zoo state!'); } }
解决方案
NGXS 18中,直接将带有依赖注入的状态类传入provideStore会导致注入器无法正确解析依赖,需要调整状态类的注册方式:
方案一:手动将状态类加入应用Providers
- 把
ZooState从provideStore的参数中移除,添加到appConfig.providers列表里,让Angular根注入器管理它的实例化。 - 使用
withStatesAPI在provideStore中注册状态,确保NGXS能正确识别并关联状态。
修改后的app.config.ts代码:
export const appConfig: ApplicationConfig = { providers: [ provideZoneChangeDetection({ eventCoalescing: true }), provideRouter(routes), // 将状态类交给Angular注入器处理依赖 ZooState, // 使用withStates注册状态 provideStore(withStates([ZooState])), { provide: CUSTOMER_CONFIG, useValue: { name: 'Alice', }, }, ], };
方案二:使用providedIn自动注册状态
给ZooState的@Injectable()装饰器添加providedIn: 'root',无需手动添加到providers数组:
修改ZooState类的装饰器:
@State<ZooStateModel>({ name: ZOO_STATE_TOKEN, defaults: { favoriteAnimal: 'Unicorn', }, }) @Injectable({ providedIn: 'root' }) // 配置自动注入到根模块 export class ZooState { // 其余代码保持不变 }
对应的app.config.ts中provideStore调整为:
provideStore(withStates([ZooState])),
两种方案都能让Angular注入器正确解析CUSTOMER_CONFIG这个InjectionToken,状态类即可正常初始化。
内容的提问来源于stack exchange,提问作者Mathyn
相关产品推荐
相关产品推荐

