javascript - Angular - Inndata ikke umiddelbart tilgjengelig på barnekomponent, hvorfor?
Jeg har en barnekalenderkomponent som mottar hendelser fra faren gjennom et inndatafelt.
@Input() private events: any[];
Når måneden endres, får forelderen nye hendelser fra en API-tjeneste og kaller barnekomponenten for å vise dem.
private populateEventsForCurrentMonth() {
return this.calendarService.getEventsAsAdmin(this.getCurrentStartDate(),
this.getCurrentEndDate())
.then((evts) => {
this.events = evts;
this.calendarChild.selectEventDaysIfApplies();
})
.catch((err) => {
console.log('error getting events', err);
});
}
Men når barnet prøver å få tilgang til hendelsene har de ikke blitt oppdatert!
Min løsning var å pakke barnfunksjonen inn i en timeout på 0 millisekunder for å plassere hele utførelsen på slutten av hendelsesloopen.
public selectEventDaysIfApplies() {
setTimeout(() => {
if (this.events) {
this.events.forEach((event) => {
let eventDate = new Date(event.starts_at);
if (this.datesBelongToSameMonth(eventDate, this.currentDate)) {
let dayWithEvent = this.days.find( (day) => {
return day.number == eventDate.getDate();
});
if (!dayWithEvent.selected) {
dayWithEvent.hasEvent = true;
}
}
});
}
}, 0);
}
Finnes det en bedre måte å gjøre det på? Kanskje en Angular beste praksis som jeg bør implementere?
Takk!
Svar #1
Dataene er ikke tilgjengelige ennå, fordi denne funksjonen håndteres synkront:
this.events = evts;
this.calendarChild.selectEventDaysIfApplies();
Umiddelbart etter at this.events er satt, kjører barnekomponentene sin metode selectEventDaysIfApplies(). Det skjer før Angulars endringsdeteksjon kjøres.
Etter min mening bør ikke foreldreskomponenten vite om noen kontroller og endringer dets barnekomponenter må gjøre.
En bedre løsning ville være å bruke livssyklus-kroken OnChanges, som utløses hver gang en input til komponenten endres.
ngOnChanges(changes: SimpleChanges) {
this.selectEventDaysIfApplies();
}
Hvis komponenten din har mer enn ett inngangspunkt, kan du sjekke hvilken som ble endret.
Les mer om dette i dokumentasjonen.
