Angular 7:从订阅内部调用 ChangeDetectorRef detectChanges() 会导致无限循环

Angular 7: ChangeDetectorRef detectChanges() causes infinite loop when called from inside a subscription

我 post 在阅读了所有与变更检测和类似 post 相关的 material 并且未能解决我的问题后来到这里。

ChangeDetectorRef detectChanges() 从订阅内部调用时会导致无限循环。如果我不调用 detectChanges,我会得到 ExpressionChangedAfterCheck 错误。我真的不知道如何解决,为什么 ExpressionChangedAfterCheck 错误会出现

ngAfterViewInit() {
    this.route.params.subscribe((params) => {
      this.userId = params.userId;
      if (this.userId != undefined) {
        this.loadActivity();
      }
      else {
        alert("Userid not supplied");
      }
      this.cdRef.detectChanges();
    });
  }

  loadActivity() {
    while(this.layers.length > 0){
      this.layers.pop();
    }
    this.loading = true;
    this.userService.authenticatedGet(ApiUrls.GetLocation(this.userId, this.activity.from.getTime(), this.activity.to.getTime()), {}).subscribe(
      (res:any) => {
        this.user = res.user;
        this.loading = false;
        // other logic
        this.cdRef.detectChanges();
        console.log("Loading is " + this.loading);
      }
    );
  }

注意:这个问题只有绑定ngIf时才会出现。

我解决了这个问题。问题不在于生命周期,而在于来自 ngx-leaflet 项目的指令 leaflet

当我删除与传单相关的指令和绑定时,所有错误都消失了。

即使这样也出现错误:

<ng-container *ngIf="!loading">
    <div
      class="map"
      leaflet
      (leafletMapReady)="onMapReady($event)"
      [leafletOptions]="options"
      [leafletLayers]="layers"
      [leafletLayersControl]="layersControl">
    </div>
</ng-container>

我尝试交替添加 detectChanges 和 markForCheck,但还是失败了。

  onMapReady(map: Map) {
    this.map = map;
    setTimeout(() => map.invalidateSize(), 1000);
    this.route.params.subscribe(params => {
      this.userId = params["userId"];
      this.loadActivity();
    });
    this.cdRef.markForCheck();
  }

最后,我在写这个答案时放弃了传单,我打算尝试 Angular-Google-Maps。

是的,A-G-M 工作正常。