Angular 提供者:使用现有的或创建一个(如果未提供)
Angular providers: Use existing or create one if not provided
在 Angular 2+ 中,如何仅在不存在实例的情况下提供 Injectable
的新实例?
我搜索并找到了 none,所以我尝试了 useFactory
。到目前为止,这是我的代码:
{
provide: ColorsService,
useFactory: (colorService: ColorsService, colors: string[]) => {
if (colorService) return colorService;
return new ColorsService(colors);
},
deps: [ColorsService, MY_COLORS],
},
除了我手动注入 MY_COLORS
令牌这一事实之外,我还收到一个奇怪的错误:
Error: Circular dep for PghChartColorsService
所以在@eko 的帮助下,我找到了这个解决方案:
@Component({
...
providers: [ColorsService],
})
export class ChildComponent {
colorService: ColorsService;
constructor(
@Self() currentColorService: ColorsService,
@Optional() @SkipSelf() parentColorService?: ColorsService,
) {
this.colorService = parentColorService ?? currentColorService;
}
}
在此示例中,parentColorService
是父组件可能提供的服务。如果未提供,我将使用在此组件中实例化的 currentColorSerivce
(无论如何实例化,这可能不是一件好事)。
还有另一种方法可以实现。
{
provide: ColorsService,
useFactory: (parentInjector: Injector, colorService?: ColorsService) => {
if (!colorService) {
const injector = Injector.create({ providers: [{ provide: ColorsService }], parent: parentInjector });
colorService = injector.get(ColorsService);
}
return colorService;
},
deps: [ Injector, [ new Optional(), new SkipSelf(), ColorsService ] ],
}
这样,每个 children 也将能够注入正确的服务
在 Angular 2+ 中,如何仅在不存在实例的情况下提供 Injectable
的新实例?
我搜索并找到了 none,所以我尝试了 useFactory
。到目前为止,这是我的代码:
{
provide: ColorsService,
useFactory: (colorService: ColorsService, colors: string[]) => {
if (colorService) return colorService;
return new ColorsService(colors);
},
deps: [ColorsService, MY_COLORS],
},
除了我手动注入 MY_COLORS
令牌这一事实之外,我还收到一个奇怪的错误:
Error: Circular dep for PghChartColorsService
所以在@eko 的帮助下,我找到了这个解决方案:
@Component({
...
providers: [ColorsService],
})
export class ChildComponent {
colorService: ColorsService;
constructor(
@Self() currentColorService: ColorsService,
@Optional() @SkipSelf() parentColorService?: ColorsService,
) {
this.colorService = parentColorService ?? currentColorService;
}
}
在此示例中,parentColorService
是父组件可能提供的服务。如果未提供,我将使用在此组件中实例化的 currentColorSerivce
(无论如何实例化,这可能不是一件好事)。
还有另一种方法可以实现。
{
provide: ColorsService,
useFactory: (parentInjector: Injector, colorService?: ColorsService) => {
if (!colorService) {
const injector = Injector.create({ providers: [{ provide: ColorsService }], parent: parentInjector });
colorService = injector.get(ColorsService);
}
return colorService;
},
deps: [ Injector, [ new Optional(), new SkipSelf(), ColorsService ] ],
}
这样,每个 children 也将能够注入正确的服务