Estoy tratando de cargar un evento desde mi API antes de que el componente se procese. Actualmente estoy usando mi servicio API que llamo desde la función ngOnInit del componente.
Mi EventRegister
componente:
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
}
}
Mi EventRegister
plantilla
<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>
Mi servicio 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();
}
}
}
El componente se procesa antes de que la llamada API en la ngOnInit
función termine de recuperar los datos. Por lo tanto, nunca puedo ver la identificación del evento en mi plantilla de vista. Parece que este es un problema ASYNC. Esperaba que el enlace del ev
( EventRegister
componente) hiciera un trabajo después de que ev
se estableciera la propiedad. Lamentablemente, no muestra el div
marcado con *ngIf="ev"
cuando se establece la propiedad.
Pregunta: ¿Estoy usando un buen enfoque? Si no; ¿Cuál es la mejor manera de cargar datos antes de que el componente comience a renderizarse?
NOTA: El ngOnInit
enfoque se utiliza en este tutorial angular2 .
EDITAR:
Dos posibles soluciones. Primero fue deshacerse del fetchEvent
y simplemente usar el servicio API en la ngOnInit
función.
ngOnInit() {
this._apiService.get.event(this.eventId).then(event => this.ev = event);
}
Segunda solución Como la respuesta dada.
fetchEvent(): Promise<EventModel> {
return this._apiService.get.event(this.eventId);
}
ngOnInit() {
this.fetchEvent().then(event => this.ev = event);
}
fuente
fetchEvent
función y solo puse laapiService.get.event
función en elngOnInit
y funcionó como asistí. ¡Gracias! Aceptaré tu respuesta tan pronto como me lo permita.Una buena solución que he encontrado es hacer en la interfaz de usuario algo como:
Solo cuando: isDataLoaded es verdadero, se representa la página.
fuente
ChangeDetectionStrategy.Push
, cambiarlo aChangeDetectionStrategy.Default
hace que sea unida en dos direcciones con la plantilla.Puede buscar previamente sus datos utilizando Resolvers en Angular2 + , los Resolvers procesan sus datos antes de que su Componente se cargue por completo.
Hay muchos casos en los que desea cargar su componente solo si sucede algo, por ejemplo, vaya al Tablero solo si la persona ya inició sesión, en este caso, los Resolvers son muy útiles.
Mire el diagrama simple que creé para usted para una de las formas en que puede usar el resolutor para enviar los datos a su componente.
Aplicar Resolver a tu código es bastante simple, creé los fragmentos para que veas cómo se puede crear el Resolver:
y en el módulo :
y puedes acceder a él en tu Componente así:
Y en la ruta algo como esto (generalmente en el archivo app.routing.ts):
fuente
Routes
matriz (generalmente en el archivo app.routing.ts ):{path: 'yourpath/:id', component: YourComponent, resolve: { myData: MyData}}
resolve: { myData: MyResolver }