typescript - Deklarere tjenesteinstans inne i konstruktøren i Angular 2


Jeg er ny på Angular 2 og Typescript og prøver å forstå DI. I all koden jeg har sett, ser jeg at variabelen som refererer til en tjeneste er typet inn i konstruktøren. Hvorfor er det slik? Hvorfor kan vi ikke ha den erklært utenfor konstruktøren, men inne i klassen?

Vurder følgende kode fra Tour of Heroes for eksempel på Angular-nettstedet:

import { Component, OnInit } from '@angular/core';
import { Hero } from './hero';
import { HeroService } from './hero.service';

@Component({
    moduleId: module.id,
    selector: 'my-dashboard',
    templateUrl: `dashboard.component.html`,
    styleUrls: ['dashboard.component.css']
})
export class DashboardComponent implements OnInit {

    heroes: Hero[] = [];

    constructor(private heroService: HeroService) { }

    ngOnInit(): void {
        this.heroService.getHeroes()
            .then(heroes => this.heroes = heroes.slice(1, 5));
    }
}

Hvis jeg erklærer heroService utenfor konstruktøren som vist under, gir appen mange feil.

export class DashboardComponent implements OnInit {

    heroes: Hero[] = [];

    constructor() { }

    private heroService: HeroService;

    ngOnInit(): void {
        this.heroService.getHeroes()
            .then(heroes => this.heroes = heroes.slice(1, 5));
    }
}

Så vidt jeg forstår, vil det å skrive det utenfor konstruktøren ikke generere en instans av tjenesteklassen HeroService, men hvorfor? (Er det en Angular-greie eller TypeScript?) I dette eksempelet er Hero også en klasse (selv om det ikke er en tjenesteklasse, er det fortsatt teknisk sett en klasse!), og vi har deklarert heroes: Hero[]=[]; utenfor konstruktøren, og det fungerer.

Svar #1

Angular DI undersøker konstruktørparameterne, og når Angular DI oppretter en ny instans av en klasse (tjeneste, komponent, direktiv, pipe), ser den etter matchende leverandører som skal sendes til konstruktøren.

Derfor,

  • injeksjon fungerer bare for klasser instansiert av DI

  • bare konstruktørparametere vurderes for injeksjon

Svar #2

Det du har beskrevet her er en egenskaps- (setter-) injeksjon som teoretisk er mulig, men som generelt ikke anbefales, også kjent som en dårlig praksis.

For å forstå dette litt bedre bør du lese om konstruktørinjeksjon og hvorfor det foretrekkes fremfor andre typer injeksjon som egenskapsinjeksjon.

Så vidt jeg vet har ikke Angular implementert andre typer for å tvinge utviklere til å bruke beste praksis, derfor kan du ikke bruke det utenfor konstruktøren.

Angular 1 refererer til dette dokumentet som du kan lese for å forstå det dypere. Ikke bekymre deg for at det er fra en tidligere versjon, dette er konseptuelle begreper som er irrelevante for rammeverket eller språket, så du kan lese det for å forstå grunnleggende.

P.S. Ikke glem at å ha en variabel i konstruktøren på den måten du har det i Typescript (med private) automatisk vil opprette en egenskap. Så når du har det i en konstruktør, injiserer Angular den der, og Typescript oppretter implisitt et felt som i ditt siste utdrag og initialiserer det fra konstruktørparameteren.

Relaterte artikler