Чудя се дали е възможно да се получат ъгловите мулти-доставчици от (в идеалния случай) всички предци.
Да кажем, че имам 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}
]
Отговори:
2 за отговор № 1Както се посочва в следния член:
Ъгловите магазини предлагат на елемента чрез използване прототипно наследство, Така че, няма значение дали използвате multi
или ще получите следния обект, който съдържа всички доставчици на текущия елемент:
Както виждате, всички доставчици са тук, но тъй като са ъглови използва квадратни скоби за да получите доставчик от елемент, ще получите само най-близкия доставчик.
За да заобиколите това, можете да използвате токена за добавяне, който използва фабрика за събиране на всички родителски доставчици:
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[]) { }
}
0 за отговор № 2
Не, не можеш да правиш това, с което се опитвашинжектиране на зависимост, доколкото знам. Когато предоставите нещо в компонент, той автоматично скрива предишните доставчици със същия знак. Това е начина, по който е предназначен да работи.
За да постигнете това, от което имате нужда, единственото решение, за което мога да се сетя, е да премине доставчиците като inputs
.
Имам предвид, comp-a
обявява доставчик. comp-b
също го прави, но приема input
съдържащи доставчик или набор от доставчици. Тогава comp-b
може да добави свой собствен доставчик към масива и да го предаде като вход за comp-c
.
Не разбирам защо точно искате това, въпреки че ...