Angular 4 ExpressionChangedAfterItHasBeenCheckedError具有可观察但不承诺

时间:2018-01-09 13:41:02

标签: angular angular-template

当子组件通过共享服务在另一个组件中设置文本时,我遇到此错误。当子组件在其onInit挂钩中从Angular Translation服务订阅Observable时会发生这种情况。但是,如果我将observable更改为承诺(.toPromise().then(..)超过.subscribe(..),问题就会消失。

我想了解原因。

我的设置......

root.component.html:

<app-page-title>{{ 'STRINGS.loading' | translate }}</app-page-title>
<div>
  <!-- view component rendered here -->
  <router-outlet (activate)='onActivate($event)'></router-outlet>
</div>

页面title.service.ts:

getPageTitle() {
  return this.pageTitle;
}
setPageTitle(pageTitle: string) {
  this.pageTitle = pageTitle;
}

页面title.component.html:

<div>
  <div *ngIf="isBack()">
    <div class="page-title-text">
     {{getPageTitle()}}
    </div>
  ...
  </div>
</div>

view.component.ts:

ngOnInit() {
  // Triggers ExpressionChangedAfterItHasBeenCheckedError 
  this.translationService.get('VIEW.title').subscribe(pageTitle => this.titleService.setPageTitle(pageTitle));

  // Works
  // this.translationService.get('VIEW.title').toPromise().then(pageTitle => this.titleService.setPageTitle(pageTitle));

}

另外需要注意的是,这是SPA。只有通过javascript加载view.component时才会显示错误,方法是通过应用程序导航到它。如果在该问题出现的视图上,并且我点击刷新,则不会发生错误。

我在这里阅读了一些关于此行为的内容:https://blog.angularindepth.com/everything-you-need-to-know-about-the-expressionchangedafterithasbeencheckederror-error-e3fd9ce7dbb4

但我仍然不明白为什么这个问题是专门用Observable发生的,而不是承诺。

1 个答案:

答案 0 :(得分:0)

view.component.ts

ngOnInit() {
   this.translationService.get('VIEW.title').subscribe(pageTitle => 
     setTimeout(() => {
       this.titleService.setPageTitle(pageTitle);
     }, 0);
   );
}