[英]Is there a way how to use Angular multi providers from all multiple levels?
I am wondering whether it is possible to get the angular multi-providers from (ideally) all ancestors. 我想知道是否有可能从(理想情况下)所有祖先获得角度多供应商。
Lets say that I have a INJECTION_TOKEN
X
and I have a component structure like this: 让我们说我有一个INJECTION_TOKEN
X
,我有一个像这样的组件结构:
<comp-a>
<comp-b>
<comp-c></comp-c>
<comp-b>
<comp-a>
comp-a
providers: providers: {provide: X, useValue: "A", multi: true}
comp-a
providers: providers: {provide: X, useValue: "A", multi: true}
comp-b
providers: providers: {provide: X, useValue: "B", multi: true}
comp-b
提供者: providers: {provide: X, useValue: "B", multi: true}
Is there a way how to get ["A", "B"]
in comp-c
when I use Dependency injection like: 当我使用依赖注入时["A", "B"]
有没有办法在comp-c
获得["A", "B"]
,如:
constructor(@Inject(X) obtainedArray:TypeOfX[]) {
console.log(obtainedArray.length); //Expected to be 2
}
I have tried to use this provider in comp-b
but it is throwing a cyclic DI expection: 我试图在comp-b
使用这个提供程序,但它正在抛出循环DI期望:
providers:[
{provide: X, useExisting: X, multi: true}
{provide: X, useValue: "B", multi: true}
]
As the following article states: 如下文所述:
Angular stores providers on element by using prototypical inheritance . Angular通过使用原型继承来存储元素的提供者。 So, never mind whether you use multi
or not you will get the following object that contains all providers on current element: 所以,不管你是否使用multi
,你将获得包含当前元素上所有提供者的以下对象:
As you can see all providers are here, but since angular just uses square brackets to get provider from element you will get only nearest provider. 正如您所看到的那样,所有提供商都在这里,但由于angular只使用方括号从元素中获取提供者,因此您只能获得最近的提供者。
To workaround this you can use addition token that uses factory to collect all parent providers: 要解决此问题,您可以使用使用工厂的附加令牌来收集所有父提供者:
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[]) { }
}
No, you can't do what you are trying to do with dependency injection, as far as I know. 不,据我所知,你不能做依赖注入你想做的事情。 When you provide something in a component, it automatically hides previous providers with the same token. 当您在组件中提供某些内容时,它会自动使用相同的令牌隐藏以前的提供程序。 This is the way it is intended to work. 这是它的工作方式。
To achieve what you need, the only solution I can think of is to pass the providers as inputs
. 为了实现您的需求,我能想到的唯一解决方案是将提供者作为inputs
。
I mean, comp-a
declares a provider. 我的意思是, comp-a
声明了一个提供者。 comp-b
also does it, but accepts an input
containing a provider or array of providers. comp-b
也可以,但接受包含提供者或提供者数组的input
。 Then comp-b
can add its own provider to the array and pass it as an input to comp-c
. 然后comp-b
可以将自己的提供者添加到数组中,并将其作为输入传递给comp-c
。
I do not understand why exactly you want this, though ... 我不明白为什么你想要这个,不过......
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.