例如,父作用域为字符串"parent"
提供SOME_TOKEN
,然后当子作用域提供相同的令牌(比方说"child"
)时,它将附加到该相同令牌提供的值列表中,使其成为["child", "parent"]
.我想要这个,因为我需要使用我不能更改的库代码.
我try 了以下函数来提供字符串,但它抛出了Circular dependency error
.
export const provideToken = (val: string) => {
return {
provide: SOME_TOKEN,
useFactory: () => {
const token = inject(SOME_TOKEN)
return token ? [...token, val] : val
}
}
}
基本上,我希望获得提供的所有值,但默认情况下,Angular 只给出最接近的值.
我可以通过一项服务实现这一点.模块或组件可以在它们的构造函数中附加到列表中,并删除它们的ngOnDestroy
中的字符串,但这似乎很容易出错.
Update个
@Anton的答案是有效的,但我也需要能够在共享模块中使用这个概念.例如:
@NgModule({
declarations: [SharedDirective],
imports: [],
exports: [SharedDirective],
providers: [provideToken("shared")]
})
export class SharedModule {}
@NgModule({
declarations: [SomeComponent],
imports: [SharedModule],
exports: [],
providers: [provideToken("some")]
})
export class SomeModule {}
如果使用skipSelf
,则只提供"some"
令牌,忽略"shared"
令牌.
Update 2个
当在提供程序中使用multi: true
时,不会忽略任何令牌,但结果数组将成为嵌套数组,因此注入服务/指令或ETC需要能够使用它.因此,我扩展了库中的指令以扁平化数组并删除其构造函数中的重复项,从而解决了我的问题.
export const provideToken = (val: string) => {
return {
provide: SOME_TOKEN,
useFactory: () => {
const token = inject(SOME_TOKEN, {skipSelf: true, optional: true})
return token ? [...token, val] : val
},
multi: true
}
}
// constructor of the extended directive
constructor(
...,
@Optional()
@Inject(SOME_TOKEN)
providedToken: MaybeArray<string>,
...
) {
if (Array.isArray(providedToken)) {
providedToken = [...new Set(providedToken.flat(Infinity))]
}
super(..., providedToken, ...)
}