Saya mencoba memuat acara dari API saya sebelum komponen dirender. Saat ini saya menggunakan layanan API yang saya panggil dari fungsi ngOnInit komponen.
EventRegister
Komponen saya :
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
}
}
EventRegister
Template saya
<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>
Layanan API saya
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();
}
}
}
Komponen dirender sebelum panggilan API dalam ngOnInit
fungsi selesai mengambil data. Jadi saya tidak pernah bisa melihat id acara di template tampilan saya. Jadi sepertinya ini adalah masalah ASYNC. Saya mengharapkan pengikatan ev
( EventRegister
komponen) untuk melakukan beberapa pekerjaan setelah ev
properti ditetapkan. Sayangnya itu tidak menunjukkan div
ditandai dengan *ngIf="ev"
saat properti ditetapkan.
Pertanyaan: Apakah saya menggunakan pendekatan yang baik? Jika tidak; Apa cara terbaik untuk memuat data sebelum komponen mulai dirender?
CATATAN: The ngOnInit
Pendekatan yang digunakan dalam tutorial angular2 .
EDIT:
Dua solusi yang mungkin. Pertama adalah membuang fetchEvent
dan hanya menggunakan layanan API dalam ngOnInit
fungsinya.
ngOnInit() {
this._apiService.get.event(this.eventId).then(event => this.ev = event);
}
Solusi kedua. Seperti jawaban yang diberikan.
fetchEvent(): Promise<EventModel> {
return this._apiService.get.event(this.eventId);
}
ngOnInit() {
this.fetchEvent().then(event => this.ev = event);
}
sumber
fetchEvent
fungsi dan hanya menempatkanapiService.get.event
fungsi dingOnInit
dan itu bekerja seperti yang saya inginkan. Terima kasih! Saya akan menerima jawaban Anda segera setelah mengizinkan saya juga.Solusi bagus yang saya temukan adalah melakukan sesuatu di UI seperti:
<div *ngIf="isDataLoaded"> ...Your page... </div
Hanya jika: isDataLoaded benar halaman dirender.
sumber
ChangeDetectionStrategy.Push
, mengubahnyaChangeDetectionStrategy.Default
menjadi dua cara terikat dengan template.Anda dapat mengambil data Anda terlebih dahulu dengan menggunakan Resolver di Angular2 + , Resolver memproses data Anda sebelum Komponen Anda dimuat sepenuhnya.
Ada banyak kasus di mana Anda ingin memuat komponen Anda hanya jika ada hal tertentu yang terjadi, misalnya menavigasi ke Dasbor hanya jika orang tersebut sudah masuk, dalam hal ini Penyelesai sangat berguna.
Lihatlah diagram sederhana yang saya buat untuk Anda untuk salah satu cara Anda dapat menggunakan resolver untuk mengirim data ke komponen Anda.
Menerapkan Resolver ke kode Anda cukup sederhana, saya membuat cuplikan agar Anda dapat melihat bagaimana Resolver dapat dibuat:
import { Injectable } from '@angular/core'; import { Router, Resolve, RouterStateSnapshot, ActivatedRouteSnapshot } from '@angular/router'; import { MyData, MyService } from './my.service'; @Injectable() export class MyResolver implements Resolve<MyData> { constructor(private ms: MyService, private router: Router) {} resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Promise<MyData> { let id = route.params['id']; return this.ms.getId(id).then(data => { if (data) { return data; } else { this.router.navigate(['/login']); return; } }); } }
dan di modul :
import { MyResolver } from './my-resolver.service'; @NgModule({ imports: [ RouterModule.forChild(myRoutes) ], exports: [ RouterModule ], providers: [ MyResolver ] }) export class MyModule { }
dan Anda dapat mengaksesnya di Komponen Anda seperti ini:
///// ngOnInit() { this.route.data .subscribe((data: { mydata: myData }) => { this.id = data.mydata.id; }); } /////
Dan di Route sesuatu seperti ini (biasanya di file app.routing.ts):
//// {path: 'yourpath/:id', component: YourComponent, resolve: { myData: MyResolver}} ////
sumber
Routes
array (biasanya di file app.routing.ts ):{path: 'yourpath/:id', component: YourComponent, resolve: { myData: MyData}}
resolve: { myData: MyResolver }