Angular - входные данные не сразу доступны для дочернего компонента, почему?

У меня есть дочерний компонент календаря, который получает события от своего отца через поле ввода.

@Input() private events: any[];

Когда месяц меняется, родитель получает новые события из службы API и вызывает дочерний компонент, чтобы показать их.

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);
});

}

Но когда ребенок пытается получить доступ к событиям, они не были обновлены!

Мой обходной путь заключался в том, чтобы обернуть дочернюю функцию в тайм-аут 0 миллисекунд, чтобы поместить все выполнение в конец цикла событий.

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);

}

Есть ли лучший способ сделать это? Может быть, лучшая практика Angular, которую я должен применить?

Спасибо!

1 ответ

Решение

Данные еще не доступны, потому что эта функция обрабатывается синхронно:

this.events = evts;
this.calendarChild.selectEventDaysIfApplies();

Незамедлительно после this.events было установлено, дочерние компоненты запускают свой метод selectEventDaysIfApplies(), Это до запуска обнаружения угловых изменений.

По моему мнению, родительский компонент не должен знать о каких-либо проверках и модификациях, которые должны делать его дочерние компоненты.

Лучшим решением было бы использовать крючок жизненного цикла OnChanges, который срабатывает всякий раз, когда изменяется вход компонента.

ngOnChanges(changes: SimpleChanges) {
  this.selectEventDaysIfApplies();
}

Если ваш компонент имеет более одного входа, вы можете проверить, какой из них был изменен.

Подробнее об этом читайте в документации.

Другие вопросы по тегам