我想知道是否有可能从(理想情况下)所有祖先那里获得角度多提供者。
假设我有一个
INJECTION_TOKEN
X
并且我有一个像这样的组件结构:
<comp-a>
<comp-b>
<comp-c></comp-c>
<comp-b>
<comp-a>
comp-a
提供商:
providers: {provide: X, useValue: "A", multi: true}
comp-b
提供商:
providers: {provide: X, useValue: "B", multi: true}
当我使用依赖注入时,有没有办法在
["A", "B"]
中获取 comp-c
,例如:
constructor(@Inject(X) obtainedArray:TypeOfX[]) {
console.log(obtainedArray.length); //Expected to be 2
}
我尝试在
comp-b
中使用此提供程序,但它引发了循环 DI 期望:
providers:[
{provide: X, useExisting: X, multi: true}
{provide: X, useValue: "B", multi: true}
]
正如以下文章所述:
Angular 通过使用原型继承在元素上存储提供者。因此,无论您是否使用
multi
,您都会得到以下对象,其中包含当前元素上的所有提供程序:
正如您所看到的,所有提供者都在这里,但由于 Angular 只是 使用方括号 从元素中获取提供者,您将只能获得最近的提供者。
要解决此问题,您可以使用使用工厂的附加令牌来收集所有父提供程序:
import { Component, VERSION, InjectionToken,
Inject, SkipSelf, Optional } from '@angular/core';
@Component({
selector: 'my-app',
template: `
<comp-a>
<comp-b>
<comp-c></comp-c>
</comp-b>
</comp-a>
`
})
export class AppComponent { }
const X = new InjectionToken('X');
const XArray = new InjectionToken('XArray');
const XArrayProvider = {
provide: XArray,
useFactory: XFactory,
deps: [X, [new SkipSelf(), new Optional(), XArray]]
};
export function XFactory(x: any, arr: any[]) {
return arr ? [x, ...arr] : [x];
}
@Component({
selector: 'comp-a',
template: `<ng-content></ng-content>`,
providers: [
{ provide: X, useValue: "A" },
XArrayProvider
]
})
export class CompA { }
@Component({
selector: 'comp-b',
template: `<ng-content></ng-content>`,
providers: [
{ provide: X, useValue: "B" },
XArrayProvider
]
})
export class CompB { }
@Component({
selector: 'comp-c',
template: `{{ tokens }}`
})
export class CompC {
constructor( @Inject(XArray) public tokens: any[]) { }
}
不,据我所知,您无法通过依赖注入做您想做的事情。当您在组件中提供某些内容时,它会自动隐藏具有相同令牌的先前提供者。这就是它的工作方式。
为了实现你所需要的,我能想到的唯一解决方案是将提供者作为
inputs
传递。
我的意思是,
comp-a
声明了一个提供者。 comp-b
也这样做,但接受包含提供者或提供者数组的 input
。然后 comp-b
可以将自己的提供者添加到数组中并将其作为输入传递给 comp-c
。
我不明白你到底为什么想要这个,但是......