/ / Има ли начин как да използвате Angular multi доставчици от всички нива? - ъглово инжектиране на зависимост

Има ли начин да се използват ъглови доставчици от множество нива? - ъглова, инжекционна зависимост

Чудя се дали е възможно да се получат ъгловите мулти-доставчици от (в идеалния случай) всички предци.

Да кажем, че имам 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[]) { }
}

Пример за Ng-run


0 за отговор № 2

Не, не можеш да правиш това, с което се опитвашинжектиране на зависимост, доколкото знам. Когато предоставите нещо в компонент, той автоматично скрива предишните доставчици със същия знак. Това е начина, по който е предназначен да работи.

За да постигнете това, от което имате нужда, единственото решение, за което мога да се сетя, е да премине доставчиците като inputs.

Имам предвид, comp-a обявява доставчик. comp-b също го прави, но приема input съдържащи доставчик или набор от доставчици. Тогава comp-b може да добави свой собствен доставчик към масива и да го предаде като вход за comp-c.

Не разбирам защо точно искате това, въпреки че ...