Обнаружение изменений происходит всякий раз, когда происходит событие браузера (или угловое событие). В этом случае происходит обнаружение изменений. Однако проблема в том, что исходная ссылка, исходящая от родительского компонента, фактически не изменилась (она изменилась с точки зрения дочернего компонента).
Другими словами, перезаписывая параметр @Input () внутри компонента, вы по существу нарушаете связь между родительским компонентом и входным параметром дочернего компонента.
Исходя из того, как работает обнаружение изменений, когда ссылки проверяются сверху вниз, неудивительно, что компонент не обновляется, если ссылка не изменилась (с точки зрения родительского компонента).
Чтобы синхронизировать привязку, настройте двустороннюю привязку с помощью EventEmitter
:
export class NavLinksComponent implements OnInit {
@Input() links: Link[] = [];
@Output() linksChange: EventEmitter<Link[]>;
constructor() {
this.linksChange = new EventEmitter<Link[]>();
}
ngOnInit() {
this.router.events.subscribe(() => {
this.updateActiveRoute();
});
}
private updateActiveRoute() {
this.currentPath = this.route.snapshot.children[0].routeConfig.path;
this.links = [...this.links].map(link => {
link.active = link.url === this.currentPath;
return link;
});
// notify the parent component that the reference has changed
this.linksChange.next(this.links);
}
}
В шаблоне вызывающего компонента настройте двустороннюю привязку, чтобы при изменении внутренней ссылки уведомлять родительский компонент также об обновлении своей ссылки:
<app-nav-links [(links)]="links" />
Таким образом, когда ссылки проверяются сверху вниз, детектор изменений будет определять, что ссылка изменилась, и правильно запускать обнаружение изменений для своих компонентов (как это должно быть для компонентов, использующих стратегию OnPush).
Это не проблема для детектора изменений по умолчанию, потому что по умолчанию детектор изменений будет проверять все связанные ссылки, независимо от того, изменились ли ссылки @Input.