现在升级到角度9主题导致ExpressionChangedAfterItHaHasBeenCheckedError

时间:2020-02-07 18:14:41

标签: angular

升级到Angular版本9后,出现一系列错误:“ ExpressionChangedAfterItHasBeenCheckedError:检查表达式后已更改。'hidden'的先前值:'true'。当前值:'false'。”

这是由我的OverlayService和App-Component之间的交互引起的。当我使用该服务更改overlayOff变量的值时,我的叠加层将启动。我得到了错误。

这不是8.x版中的行为。每次我从服务器对DOM进行更改时,我都会经常在项目中关闭和打开叠加层。有关如何解决此问题的建议。

app.component.html

<div class="container-fluid">
  <div [hidden]="overlayOff" id="overlay">
    <mp-loading marginTop="25"></mp-loading>
  </div>     
  <router-outlet></router-outlet>
</div>

app.component.ts

    @Component({
    // tslint:disable-next-line:component-selector
    selector: 'app-root',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.css']
    })
    export class AppComponent implements OnInit, OnDestroy {

     private overlaySubscription: Subscription;
       overlayOff = true;

     constructor({
       private overlayService: OverlayService) 
     }

     ngOnInit() {
       this.overlaySubscription =      this.overlayService.toggleOverlay
        .subscribe(nextValue => {
           this.overlayOff = (nextValue === undefined) ?  !this.overlayOff : nextValue;
    // console.log('OverlayOff:' + this.overlayOff);
          });
   }

      ngOnDestroy() {
        this.overlaySubscription.unsubscribe();
      }

     }

overlay.service.ts

import { Injectable } from '@angular/core';
import { Subject } from 'rxjs';

 @Injectable({
   providedIn: 'root'
  })
 export class OverlayService {
    toggleOverlay: Subject<boolean> = new Subject();
    constructor() { }

    overlayOn() {
       // console.log('overlay On');
     this.toggleOverlay.next(false);
    }
    overlayOff() {
       this.toggleOverlay.next(true);
     }
   }

2 个答案:

答案 0 :(得分:0)

使用async管道会更好。这样,您根本就不必使用订阅

<div class="container-fluid">
  <div [hidden]="overlayOff$ | async" id="overlay">
    <mp-loading marginTop="25"></mp-loading>
  </div>     
  <router-outlet></router-outlet>
</div>

component.ts:

readonly overlayOff$ = this.overlayService.toggleOverlay.pipe(
  pairwise(),
  map(([prev, next]) => next == null ?  !prev : next),
  startWith(true)
);

此外,建议使用changeDetectionStrategy OnPush。这是为了防止错误检测可能会发现不必要的更改

答案 1 :(得分:0)

虽然我不知道为什么会发生问题,但似乎对我有用的解决方案如下。

首先在app.component.ts中添加AfterContentChecked生命周期挂钩。

创建一个新的私有变量overlayResponseHolder

下一个更改订阅

.subscribe(nextValue => {
    this.overlayResponseHolder = nextValue;
  });

创建一个新函数ngAfterContentChecked

ngAfterContentChecked() {
  this.overlayOff = this.overlayResponseHolder;
}

不确定是解决方案还是集群,但现在它又可以工作了。

相关问题