我想知道是否有可能从(理想情况下)所有祖先获得角度多供应商。
假设我有一个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}
]
答案 0 :(得分:4)
如下文所述:
Angular通过原型继承在元素上存储提供者。所以,不管你是否使用multi
,你都会得到包含当前元素上所有提供者的以下对象:
正如您所看到的那样,所有提供商都在这里,但由于角度只是uses square brackets从元素获得提供者,您将只获得最近的提供者。
要解决此问题,您可以使用使用工厂收集所有父提供者的附加令牌:
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[]) { }
}
<强> Ng-run Example 强>
答案 1 :(得分:0)
不,据我所知,你不能做依赖注入的事情。当您在组件中提供某些内容时,它会自动使用相同的令牌隐藏以前的提供程序。这是它的工作方式。
为了实现您的需求,我能想到的唯一解决方案是将提供者作为inputs
传递。
我的意思是,comp-a
声明提供者。 comp-b
也会这样做,但接受包含提供者或提供者数组的input
。然后comp-b
可以将自己的提供程序添加到数组中,并将其作为输入传递给comp-c
。
我不明白为什么你想要这个,不过......