Ich versuche, ein Ereignis aus meiner API zu laden, bevor die Komponente gerendert wird. Derzeit verwende ich meinen API-Dienst, den ich über die ngOnInit-Funktion der Komponente aufrufe.
Meine EventRegister
Komponente:
import {Component, OnInit, ElementRef} from "angular2/core";
import {ApiService} from "../../services/api.service";
import {EventModel} from '../../models/EventModel';
import {Router, ROUTER_DIRECTIVES, ROUTER_PROVIDERS, RouteConfig, RouteParams, RouterLink} from 'angular2/router';
import {FORM_PROVIDERS, FORM_DIRECTIVES, Control} from 'angular2/common';
@Component({
selector: "register",
templateUrl: "/events/register"
// provider array is added in parent component
})
export class EventRegister implements OnInit {
eventId: string;
ev: EventModel;
constructor(private _apiService: ApiService,
params: RouteParams) {
this.eventId = params.get('id');
}
fetchEvent(): void {
this._apiService.get.event(this.eventId).then(event => {
this.ev = event;
console.log(event); // Has a value
console.log(this.ev); // Has a value
});
}
ngOnInit() {
this.fetchEvent();
console.log(this.ev); // Has NO value
}
}
Meine EventRegister
Vorlage
<register>
Hi this sentence is always visible, even if `ev property` is not loaded yet
<div *ngIf="ev">
I should be visible as soon the `ev property` is loaded. Currently I am never shown.
<span>{{event.id }}</span>
</div>
</register>
Mein API-Service
import "rxjs/Rx"
import {Http} from "angular2/http";
import {Injectable} from "angular2/core";
import {EventModel} from '../models/EventModel';
@Injectable()
export class ApiService {
constructor(private http: Http) { }
get = {
event: (eventId: string): Promise<EventModel> => {
return this.http.get("api/events/" + eventId).map(response => {
return response.json(); // Has a value
}).toPromise();
}
}
}
Die Komponente wird gerendert, bevor der API-Aufruf in der ngOnInit
Funktion das Abrufen der Daten abgeschlossen hat. Daher wird die Ereignis-ID in meiner Ansichtsvorlage nie angezeigt. Es sieht also so aus, als wäre dies ein ASYNC-Problem. Ich habe erwartet, dass die Bindung der ev
( EventRegister
Komponente) einige Arbeit leistet, nachdem die ev
Eigenschaft festgelegt wurde. Leider wird das mit div
gekennzeichnete nicht angezeigt, *ngIf="ev"
wenn die Eigenschaft festgelegt wird.
Frage: Benutze ich einen guten Ansatz? Wenn nicht; Was ist der beste Weg, um Daten zu laden, bevor die Komponente mit dem Rendern beginnt?
HINWEIS: Der ngOnInit
Ansatz wird in diesem Angular2-Lernprogramm verwendet .
BEARBEITEN:
Zwei mögliche Lösungen. Zuerst musste fetchEvent
der API-Dienst in der ngOnInit
Funktion verworfen und einfach verwendet werden.
ngOnInit() {
this._apiService.get.event(this.eventId).then(event => this.ev = event);
}
Zweite Lösung. Wie die gegebene Antwort.
fetchEvent(): Promise<EventModel> {
return this._apiService.get.event(this.eventId);
}
ngOnInit() {
this.fetchEvent().then(event => this.ev = event);
}
quelle
fetchEvent
Funktion entfernt und sie einfach in dieapiService.get.event
FunktionngOnInit
eingefügt, und es hat so funktioniert, wie ich es beabsichtigt habe. Vielen Dank! Ich werde Ihre Antwort akzeptieren, sobald es mir auch erlaubt.Eine nette Lösung, die ich gefunden habe, besteht darin, auf der Benutzeroberfläche Folgendes zu tun:
Nur wenn: isDataLoaded true ist, wird die Seite gerendert.
quelle
ChangeDetectionStrategy.Push
undChangeDetectionStrategy.Default
es so geändert , dass es in beide Richtungen mit der Vorlage verbunden ist.Sie können Pre-Fetch - Daten unter Verwendung von Resolver in Angular2 + verarbeiten Resolver Ihre Daten vor Ihrer Komponente vollständig geladen werden.
In vielen Fällen möchten Sie Ihre Komponente nur laden, wenn bestimmte Ereignisse auftreten. Navigieren Sie beispielsweise nur dann zum Dashboard, wenn die Person bereits angemeldet ist. In diesem Fall sind Resolver sehr praktisch.
Schauen Sie sich das einfache Diagramm an, das ich für Sie erstellt habe, um zu erfahren, wie Sie mit dem Resolver die Daten an Ihre Komponente senden können.
Das Anwenden von Resolver auf Ihren Code ist ziemlich einfach. Ich habe die Snippets erstellt, damit Sie sehen können, wie der Resolver erstellt werden kann:
und im Modul :
und Sie können in Ihrer Komponente wie folgt darauf zugreifen :
Und in der Route so etwas (normalerweise in der Datei app.routing.ts):
quelle
Routes
den Routenkonfigurationseintrag unter dem Array verpasst (normalerweise in der Datei app.routing.ts ):{path: 'yourpath/:id', component: YourComponent, resolve: { myData: MyData}}
resolve: { myData: MyResolver }