@stepa90

Как исправить ExpressionChangedAfterItHasBeenCheckedError при использовании router.events и navigate?

Реализовал спиннер перехода между дочерними компонентами c помощью router.events.
Template основного компонента
<div [ngClass]="{'loading-class':loading}">
<router-outlet></router-outlet>
</div>


Сам компонент

export class MyComponent {
    loading: boolean;
    constructor(router: Router) {
        router.events
            .pipe(
                filter(e => e instanceof NavigationStart || e instanceof NavigationEnd),
                map(e => e instanceof NavigationStart),
                distinctUntilChanged()
            )
            .subscribe(loading => this.loading = loading);
    }
}

В итоге NavigateStart показываем колесо загрузки, а NavigateEnd показываем страницу.
Все работает замечательно, но если происходит навигация на тот же роутер (url) где мы находимся, например когда когда нужно очистить параметры в url, из-за того, что мы уже инициализировали компонент возникает ошибка ExpressionChangedAfterItHasBeenCheckedError .

Гугл помог только найти костыльные решения - сделать изменение асинхронным (setTimeout или EventEmitter(true)) либо принудительно сменять окружение. В этой статье они описываются и там же говорится что такие решения плохие.

Сам придумал только запоминать url при навигации и затем его проверять с новым при переходах, но это тоже кастыль.
Возможно есть более элегантное решение. Я уверен кто-то уже сталкивался с этим.
  • Вопрос задан
  • 174 просмотра
Решения вопроса 1
Xuxicheta
@Xuxicheta Куратор тега Angular
инженер
export class MyComponent {
  loadingClass = this.createLoadingClass();

  constructor(router: Router) {}

  private createLoadingClass(): Observable<boolean> {
    return router.events.pipe(
      map(e => e instanceof NavigationStart),
    );
  }
}


<div [class.loading]="loadingClass | async">

А вот зачем это нужно? Почему переход по роуту занимает какое-то время?
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы