我有一個組件可以更改應用程序全局服務中的值,並且有時會看到Expression has changed after it was checked. Previous value: 'false'. Current value: 'true'
消息。我知道這些可以通過啓用生產模式來消除,但我更願意瞭解如何正確執行此操作。如何正確更改導致父組件中的視圖更改的`Observable`?
TL;博士:我嫌疑這可以通過某種方式告訴變化檢測父也將改變,解決了,讓我怎麼走了變化檢測樹?家長和孩子之間有一個<router-outlet>
可能也可能不重要。
充分說明,如果我有一個完全地錯誤的認識: 有問題的代碼大致是這樣的:該ChildComponent
有兩個訂閱需要得到滿足,一旦他們已經準備好,顯示組件和一些看法變量重置爲有意義的值。
this._routeParams.params.subscribe(params => {
var pageId = params['pageId'];
this._projectService.activeProject
.subscribe(res => {
// Project is loaded, display the correct page to edit
this._project = res;
this._page = this._project.getPageById(pageId);
// The active page has changed: Reset render preview and sidebar
this.doRenderPreview = false;
// <<ERROR>> triggered by this line
this._sidebarService.showSidebar(SidebarComponent.SIDEBAR_IDENTIFIER);
});
})
到SidebarService.showSidebar()
呼叫基本更新此全局可用SidebarService
然後將其用於實際呈現在ParentComponent
側欄的一個Observable
。
// this.model is a BehaviourSubject
showSidebar(newType : string, param? : any) {
if (!this.isKnownType(newType)) {
throw new Error(`Unknown sidebar type: ${newType}`);
}
this._model.next({
type : newType,
param : param
});
}
還有另一種觀察到,只有大約傳播的可見性狀態的變化,這是需要知道是否有一個工具,但不關心細節的重要部件。
get isSidebarVisible() : Observable<boolean> {
return (this._model.map(s => !!s));
}
爲了使側邊欄,在ParentComponent
需要更新其佈局,這是發生錯誤:
<!-- Error: Expression has changed after it was checked. Previous value: 'false'. Current value: 'true' -->
<div *ngIf="isSidebarVisible | async"
class="sidebar">
<sidebar-loader></sidebar-loader>
</div>
<div *ngIf="isSidebarVisible | async"
class="sidebar-hack">
<!-- Dirty hack to ensure the main content is not too wide -->
</div>
的isSidebarVisible
屬性僅僅是一個快捷方式到全球服務:
get isSidebarVisible() {
return (this._sidebarService.isSidebarVisible);
}
我嫌疑人即問題是Editor
組件導致更改它的父組件。但我在其他地方也有類似的代碼,這種情況下的主要區別可能是是孩子通過<router-outlet>
加載?
編輯:this._sidebarService.isSidebarVisible.subscribe(v => this._sidebarVisible = v);
:避免在視圖中async
管,而是「緩存」 isSidebarVisible
父,並通過訂閱更新時的行爲是一樣的。
感謝您的建議,我相應地更新了帖子。可悲的是將訂閱拉入組件並沒有幫助,錯誤保持完全一樣。據我所知,使用'EventEmitter'不能通過''工作。還是我誤會了? –
它確實工作是的,我們在工作中使用它,但是你可能想要爲它創建一個包裝 – Colum