我有兩個組件:ParentComponent > ChildComponent
和一個服務,例如, TitleService
。更新父組件中父值的值會導致ExpressionChangedAfterItHasBeenCheckedError發生角度
ParentComponent
看起來是這樣的:
export class ParentComponent implements OnInit, OnDestroy {
title: string;
private titleSubscription: Subscription;
constructor (private titleService: TitleService) {
}
ngOnInit(): void {
// Watching for title change.
this.titleSubscription = this.titleService.onTitleChange()
.subscribe(title => this.title = title)
;
}
ngOnDestroy(): void {
if (this.titleSubscription) {
this.titleSubscription.unsubscribe();
}
}
}
ChildComponent
看起來是這樣的:
export class ChildComponent implements OnInit {
constructor (
private route: ActivatedRoute,
private titleService: TitleService
) {
}
ngOnInit(): void {
// Updating title.
this.titleService.setTitle(this.route.snapshot.data.title);
}
}
的想法很簡單:ParentController
顯示標題在屏幕上。爲了始終呈現其訂閱TitleService
的實際標題並監聽事件。當標題被改變時,事件發生並且標題被更新。
當加載ChildComponent
時,它從路由器(它會動態解析)獲取數據並告知TitleService
用新值更新標題。
問題是這樣的解決方案會導致此錯誤:
Error: ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: 'undefined'. Current value: 'Dynamic Title'.
它看起來像值在變化檢測一輪更新。
我是否需要重新安排代碼以實現更好的實現,還是必須在某處啓動另一個更改檢測?
我可以移動
setTitle()
和onTitleChange()
調用推崇構造函數,但我讀過,它被認爲是一種不好的做法做任何「繁重工作」在構造邏輯,除了初始化局部性質。此外,標題應由子組件確定,因此無法從中提取此邏輯。
更新
我已經實現了一個小例子,以便更好地說明這個問題。你可以在the GitHub repository找到它。
<p>Parent Component</p>
<p>Title: "<span *ngIf="title">{{ title }}</span>"</p>
<hr>
<app-child></app-child>
您是否嘗試使用ngAfterViewInit代替ParentComponent中的ngOnInit? –
你可以顯示你的路線配置嗎? –
還有組件模板? –