J'essaie de charger un événement depuis mon API avant que le composant ne soit rendu. Actuellement, j'utilise mon service API que j'appelle depuis la fonction ngOnInit du composant.
Mon EventRegister
composant:
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
}
}
Mon EventRegister
modèle
<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>
Mon service API
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();
}
}
}
Le composant est rendu avant que l'appel d'API dans la ngOnInit
fonction ne récupère les données. Je ne vois donc jamais l'ID d'événement dans mon modèle de vue. Il semble donc que ce soit un problème ASYNC. Je m'attendais à ce que la liaison du ev
( EventRegister
composant) fasse un certain travail une fois la ev
propriété définie. Malheureusement, il n'affiche pas le div
marqué avec *ngIf="ev"
lorsque la propriété est définie.
Question: Est-ce que j'utilise une bonne approche? Si non; Quelle est la meilleure façon de charger des données avant que le composant ne commence à être rendu?
REMARQUE: l' ngOnInit
approche est utilisée dans ce didacticiel angular2 .
ÉDITER:
Deux solutions possibles. La première était d'abandonner le fetchEvent
et d'utiliser simplement le service API dans la ngOnInit
fonction.
ngOnInit() {
this._apiService.get.event(this.eventId).then(event => this.ev = event);
}
Deuxième solution. Comme la réponse donnée.
fetchEvent(): Promise<EventModel> {
return this._apiService.get.event(this.eventId);
}
ngOnInit() {
this.fetchEvent().then(event => this.ev = event);
}
la source
fetchEvent
fonction entière et mis simplement laapiService.get.event
fonction dans lengOnInit
et cela a fonctionné comme prévu. Merci! J'accepterai votre réponse dès que cela me le permettra aussi.Une bonne solution que j'ai trouvée est de faire sur l'interface utilisateur quelque chose comme:
Uniquement lorsque: isDataLoaded est true, la page est rendue.
la source
ChangeDetectionStrategy.Push
, le changer en leChangeDetectionStrategy.Default
rend lié dans les deux sens avec le modèle.Vous pouvez pré-récupérer vos données en utilisant des résolveurs dans Angular2 + , les résolveurs traitent vos données avant le chargement complet de votre composant.
Dans de nombreux cas, vous souhaitez charger votre composant uniquement s'il se passe quelque chose, par exemple, accédez au tableau de bord uniquement si la personne est déjà connectée, dans ce cas, les résolveurs sont très pratiques.
Regardez le diagramme simple que j'ai créé pour vous pour une des façons dont vous pouvez utiliser le résolveur pour envoyer les données à votre composant.
L'application de Resolver à votre code est assez simple, j'ai créé les extraits pour vous permettre de voir comment le Resolver peut être créé:
et dans le module :
et vous pouvez y accéder dans votre composant comme ceci:
Et dans la Route quelque chose comme ça (généralement dans le fichier app.routing.ts):
la source
Routes
tableau (généralement dans le fichier app.routing.ts ):{path: 'yourpath/:id', component: YourComponent, resolve: { myData: MyData}}
resolve: { myData: MyResolver }