typescript - Angular 2 ngOnInit kalt to ganger med feil


Jeg støtte på en merkelig feil i Angular 2. Jeg har to lignende komponenter med lignende maler og lignende tjenester. Her er det grunnleggende om hvordan de fungerer:

Komponent :

theData: any;

constructor(private _theService: TheService) {}

ngOnInit() {
    this._theService.getData()
        .subscribe(data => {
            this.theData = data;
        });
}

Service :

private _url = "http://url.net/api/Data";

constructor(private _http: Http) {
}

getData() {
    return this._http.get(this._url)
        .map(res => res.json());
}

dette returnerer et array med objekter, som:

[
    {name: "Name 1"},
    {name: "Name 2"}
]

og malen viser dem slik:

<div *ngFor="let item of theData">{{ item.name }}</div>

Deretter kan du klikke på et element hvor du blir tatt til en side som følger samme strategi som ovenfor, bortsett fra at tjenesten/api bare returnerer ett objekt og malen bruker ikke *ngFor fordi det bare er ett element å vise.

Så det ser ut som:

theItem = {name: "Name 1"} // what the service returns

<div>{{ theItem.name }}</div>

Alt fungerer bra når jeg viser alle elementene, men når jeg klikker på de enkelte elementene, blir OnInit kalt to ganger og jeg får en feil i platform-browser.umd.js, som egentlig er en feil i malen fordi det står at den ikke kan lese egenskapen name av undefined (som er theItem).

Jeg løste dette problemet ved å endre malen for individuelle elementer til:

<div>{{ theItem?.name }}</div>

Først trodde jeg problemet var at malen ble rendret før dataene hadde lastet fra tjenesten, så det å legge til ? løste det. Men bør ikke malen lastes ETTER at ngOnInit har fullført? Mitt spørsmål er, hvorfor løste det å legge til ? dette problemet, selv om jeg ikke trenger det i den første malen når jeg laster alle elementene?

Takk.

Svar #1

Fordi get er asynkron, begynner den faktisk å gjengi malen før dataene er lastet. Den vil starte tjenestekallet og vil ikke vente, den vil fortsette behandlingen. Å legge til ? lar det være undefined og deretter gjengi passende når dataene er lastet.

Relaterte artikler