Как исправить ExpressionChangedAfterItHasBeenCheckedError на угловой панели расширения матов - PullRequest
2 голосов
/ 05 ноября 2019

Цель: если пользователь щелкает по любому элементу top уровня mat-extension-panel-header-header, свернуть все открытые вложенные элементы уровня заголовка mat-extension-panel-header, например:

  1. Нажмите Основной заголовок 1 , чтобы развернуть его
  2. Нажмите Подзаголовок 1 , чтобы развернуть его
  3. Нажмите Основной заголовок1 , чтобы свернуть его. Это должно вызвать событие, которое сворачивается Подзаголовок 1 .

По сути, это «служебная задача», которую нужно очистить, если пользователь оставляет панели развернутыми.

Проблема:Если дважды быстро щелкнуть один из элементов заголовка mat-extension-panel-header уровня top (например, пока анимации развертывания / свертывания все еще работают), в консоли выдается следующая ошибка:

ExpressionChangedAfterItHasBeenCheckedError: Выражение изменилось после его проверки. Предыдущее значение: «mat-extended: false». Текущее значение: 'mat-extended: true'.

Если вы продолжите вызывать эти ошибки, в конечном счете, они будут продолжать работать бесконечно и браузер полностью заблокируется.

См. Проект Stackblitz здесь: https://stackblitz.com/edit/expression-changed-error

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

Ответы [ 3 ]

3 голосов
/ 05 ноября 2019

Удалите следующий код из html, чтобы устранить ошибку.

(afterExpand)="collapseSub(panel)"

Из функции collapseSub я вижу, что вы пытаетесь закрыть панели и открыть только выбранную. Но это уже обработано по умолчанию. Вы пытаетесь изменить развернутое состояние панели, когда оно уже обработано по умолчанию;

1 голос
/ 05 ноября 2019

Простое решение - запланировать изменения после окончания текущего цикла событий, используя setTimeout:

collapseSub = (panel: MatExpansionPanel) => {
  setTimeout(() => {
    const items = this.matExpansionPanelQueryList.filter(item => item.expanded === true);
    if (items) {
      items.forEach(item => {
        item.close();
      });
    }
    panel.open();
  });
}
1 голос
/ 05 ноября 2019

Если вы не хотите удалять (afterExpand)="collapseSub(panel)", вы можете попробовать это решение.

constructor(private fb: FormBuilder, private cdRef: ChangeDetectorRef) {
  }

collapseSub = (panel: MatExpansionPanel) => {
    const items = this.matExpansionPanelQueryList.filter(item => item.expanded === true);
    if (items) {
      items.forEach(item => {
        item.close();
      });
    }
    panel.open();
    this.cdRef.detectChanges();
  }

this.cdRef.detectChanges(); добавление этой строки поможет вам.

...