Próbuję załadować zdarzenie z mojego interfejsu API przed renderowaniem składnika. Obecnie używam mojej usługi API, którą wywołuję z funkcji ngOnInit komponentu.
Mój EventRegister
komponent:
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
}
}
Mój EventRegister
szablon
<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>
Moja usługa 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();
}
}
}
Komponent jest renderowany, zanim wywołanie API w ngOnInit
funkcji zakończy się pobieraniem danych. Dlatego nigdy nie widzę identyfikatora zdarzenia w moim szablonie widoku. Więc wygląda na to, że jest to problem ASYNC. Spodziewałem się, że powiązanie ev
( EventRegister
komponentu) wykona trochę pracy po ustawieniu ev
właściwości. Niestety, nie pokazuje on div
oznaczonego symbolem, *ngIf="ev"
gdy właściwość zostanie ustawiona.
Pytanie: Czy stosuję dobre podejście? Jeśli nie; Jaki jest najlepszy sposób na załadowanie danych przed rozpoczęciem renderowania komponentu?
UWAGA:ngOnInit
podejście jest stosowane w tym angular2 tutorialu .
EDYTOWAĆ:
Dwa możliwe rozwiązania. Pierwszym było porzucenie fetchEvent
i użycie usługi API w ngOnInit
funkcji.
ngOnInit() {
this._apiService.get.event(this.eventId).then(event => this.ev = event);
}
Drugie rozwiązanie. Podobnie jak udzielona odpowiedź.
fetchEvent(): Promise<EventModel> {
return this._apiService.get.event(this.eventId);
}
ngOnInit() {
this.fetchEvent().then(event => this.ev = event);
}
źródło
fetchEvent
funkcję i po prostu umieściłemapiService.get.event
funkcję wngOnInit
i działało tak, jak zamierzałem. Dzięki! Przyjmę Twoją odpowiedź, gdy tylko mi na to pozwoli.Dobrym rozwiązaniem, które znalazłem, jest zrobienie w interfejsie użytkownika czegoś takiego:
Strona jest renderowana tylko wtedy, gdy: isDataLoaded ma wartość true.
źródło
ChangeDetectionStrategy.Push
, używałem, zmieniając go tak, abyChangeDetectionStrategy.Default
był dwukierunkowo powiązany z szablonem.Możesz pobrać dane z wyprzedzeniem za pomocą programów do rozpoznawania nazw w Angular2 + , programy do rozpoznawania nazw przetwarzają dane przed pełnym załadowaniem komponentu.
Jest wiele przypadków, w których chcesz załadować swój komponent tylko wtedy, gdy coś się dzieje, na przykład nawigacja do Dashboardu tylko wtedy, gdy osoba jest już zalogowana, w tym przypadku Resolwery są bardzo przydatne.
Spójrz na prosty diagram, który dla Ciebie stworzyłem, przedstawiający jeden ze sposobów wykorzystania resolwera do wysyłania danych do Twojego komponentu.
Zastosowanie resolvera do twojego kodu jest dość proste, stworzyłem fragmenty, aby zobaczyć, jak można utworzyć Resolver:
aw module :
i możesz uzyskać do niego dostęp w swoim komponencie w następujący sposób:
A w Route coś takiego (zwykle w pliku app.routing.ts):
źródło
Routes
tablicą (zwykle w pliku app.routing.ts ):{path: 'yourpath/:id', component: YourComponent, resolve: { myData: MyData}}
resolve: { myData: MyResolver }