javascript - Angular2 - injiser i @Injectable


Jeg har en Angular2-app med en service som brukes for å hente data fra en API. Følgende eksempel ønsker jeg å lage en separat fil som skal inneholde noen konfigurasjonsdata. Problemet mitt er at servicen min har en @Injectable()-dekoratør, og jeg er ikke sikker på om jeg kan gi den et provide-array i metadataene der jeg vil injisere konfigurasjonen som vist i veiledningen. Enhver som noen gang har møtt et slikt problem er velkommen til å dele sin løsning :)

Svar #1

Faktisk utnytter Angular2 hierarkiske injektorer, og injektorer er koblet til komponenter. Kort sagt kan du definere leverandører enten kun på komponenter (providers-egenskapen) eller på applikasjonsnivå (bootstrap-funksjonen).

Når det gjelder tjenester, vil de kunne bruke leverandører som er synlige for komponenten som initierte kallet, men du kan ikke definere leverandører på deres nivåer.

Her er et eksempel:

Application
     |
AppComponent
     |
ChildComponent
  getData()     --- Service1 --- Service2

I en slik applikasjon har vi tre injektorer:

  • Applikasjonsinjektoren som kan konfigureres ved å bruke den andre parameteren i bootstrap-funksjonen
  • Injektøren AppComponent kan konfigureres ved å bruke providers-attributtet til denne komponenten. Den kan «se» elementer som er definert i applikasjonsinjektøren. Dette betyr at hvis en provider ikke finnes i denne provideren, vil den automatisk søke i denne foreldreinjektøren. Hvis den ikke finnes der heller, vil en «provider not found»-feil bli kastet.
  • Injektøren ChildComponent som vil følge de samme reglene som AppComponent-injektøren. For å injisere elementer som er involvert i injeksjonskjeden som utføres for komponenten, vil leverandører først bli søkt etter i denne injektøren, deretter i AppComponent-injektøren og til slutt i applikasjonsinjektøren.

Dette betyr at når man prøver å injisere Service1 i ChildComponent-konstruktøren, vil Angular2 se i ChildComponent-injeksjonen, deretter i AppComponent-injeksjonen og til slutt i applikasjonsinjeksjonen.

Siden Service2 må injiseres i Service1, vil den samme oppløsningsbehandlingen bli gjort: ChildComponent-injektor, AppComponent-injektor og applikasjonsinjektor.

Dette betyr at både Service1 og Service2 kan spesifiseres på hvert nivå i henhold til dine behov ved å bruke providers-attributtet for komponenter og den andre parameteren til bootstrap-funksjonen for applikasjonsinjektoren.

Dette svaret kan hjelpe deg:

  • Hva er den beste måten å injisere en tjeneste i en annen på i Angular 2 (Beta)?

Svar #2

Det er litt rart, men bare komponenter kan konfigurere avhengighetsinjeksjon i Angular (vel, og bootstrap(), men det er i hovedsak det samme som rotkomponenten). Det vil si, bare komponenter kan spesifisere leverandører.

Som @Thierry nevner i sitt svar, vil hver komponent i komponenttreet få en tilknyttet "injector" hvis komponenten har en providers-array spesifisert. Vi kan tenke på dette som et injector-tre, som vanligvis er (mye) sparsommere enn komponenttreet. Når en avhengighet må løses, blir dette injector-treet konsultert. Den første injectoren som kan tilfredsstille avhengigheten gjør det. Injector-treet blir fulgt oppover, mot rotkomponenten/injectoren.

Så, for at tjenesten din skal kunne injisere en konfigurasjonsobjektavhengighet, må det konfigurasjonsobjektet først registreres hos en injector. Det vil si, i en komponents providers-array, kall
provide(stringToken eller OpaqueToken, {useValue: MyConfigObject} )
Denne registreringen må skje et sted på eller over komponenten der du ønsker å bruke/injisere tjenesten din.

Tjenesten din bør da kunne @Inject det registrerte konfigurasjonsobjektet, fordi det vil finne det i injektortreet.

Merk, siden kun komponenter kan konfigurere leverandører, støtter ikke @Injectable()-dekoren noen konfigurasjonsalternativer, så et providers-array støttes ikke.

Relaterte artikler