延迟加载路由和异步管道时使用推送策略的ExpressionChangedAfterItHasBeenCheckedError

时间:2018-11-28 20:03:39

标签: angular rxjs

从组件1的模块切换到组件2的模块后,出现以下错误:

  

错误错误:ExpressionChangedAfterItHasBeenCheckedError:表达   检查后已更改。前一个值:'ngIf:[对象   宾语]'。当前值:'ngIf:[object Object],[object   对象],[对象对象],[对象对象],[对象对象],[对象   对象],[对象对象],[对象对象],[对象对象]'

两个模块都使用

  

ChangeDetectionStrategy.OnPush

当我订阅自己的内容时,一切都很好:

this.bookings$.pipe(takeUntil(this._destroy$)).subscribe(res => console.log(res));

但是,一旦我使用异步管道进行订阅,更改检测就会中断:

<ion-list *ngIf="bookings$ | async as bookings; else loading">
</ion-list>

更改路线时,模块/组件2的初始化比破坏组件1更快。因此,组件1得到的更改(filteredBookings)由组件2在底特律之前的日期更改启动。但这不应该成为问题吗?

服务:

constructor(
  private afs: AngularFirestore
) {
  this.bookingsCollection = afs.collection<Booking>('bookings');
  this.bookingsCollection
    .snapshotChanges()
    .pipe(
      takeUntil(this._destroy$),
      map(actions => {
        return actions.map(a => {
          const data = a.payload.doc.data() as Booking;
          const id = a.payload.doc.id;
          return {id, ...data};
        });
      })
    )
    .subscribe((bookings: Booking[]) => {
      this._bookings.next([...bookings]);
      this.refreshFilteredBookings();
    });
  this.bookings$ = this._bookings
    .asObservable()
    .pipe(
      filter(bookings => bookings !== null)
    );
  this.filteredBookings$ = this._filteredBookings
    .asObservable()
    .pipe(
      filter(bookings => bookings !== null),
    );

}

private refreshFilteredBookings(): void {
  const bookings: Booking[] = JSON.parse(JSON.stringify(this._bookings.value));
  const filteredBookings: Booking[] = bookings.filter(booking =>
    moment(booking.date).isBetween(this.minDate, this.maxDate, null, '[]')
  );
  this._filteredBookings.next(filteredBookings);
}

setDate(date: Moment, type: string) {
  this.minDate = date.startOf(type as unitOfTime.StartOf).format();
  this.maxDate = date.endOf(type as unitOfTime.StartOf).format();
  if (this._bookings.value) {
    this.refreshFilteredBookings();
  }
}

组件1:

ngOnInit() {
   this.bookings$ = this._bookingService.filteredBookings$;
}

组件2:

ngOnInit() {
   this.view = 'month';
   this.date = moment().format();
   this.onDateChange();
}

onDateChange() {
   const m = moment(this.date);
   this._bookingService.setDate(m, this.view);
}

1 个答案:

答案 0 :(得分:2)

您是否正在使用Angular 6?

问题可能出在延迟加载模块中,它不会在导航到另一个组件(组件2)时破坏当前组件(组件1)。因此组件1的asycnPipe不会退订。

组件2正在初始化时,它更改了共享服务的值, 组件1正在订阅共享服务,它正在尝试重新呈现视图并导致此问题。

我认为我们可以通过从组件中订阅可观察对象并将值传递给视图来解决,但这不是一个好方法。

You can check other way at here


更新: 就我而言,我将 changeDetectionStrategy Default 更改为 OnPush ,这解决了我的问题。