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.