Реализовал спиннер перехода между дочерними компонентами 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 при навигации и затем его проверять с новым при переходах, но это тоже кастыль.
Возможно есть более элегантное решение. Я уверен кто-то уже сталкивался с этим.