【问题标题】:ExpressionChangedAfterItHasBeenCheckedError using push strategy when lazy loading route and async pipe延迟加载路由和异步管道时使用推送策略的 ExpressionChangedAfterItHasBeenCheckedError
【发布时间】:2018-12-18 17:03:36
【问题描述】:

当我从带有组件 1 的模块切换到带有组件 2 的模块时,我收到以下错误:

错误错误:ExpressionChangedAfterItHasBeenCheckedError:表达式 检查后有变化。以前的值:'ngIf: [object 目的]'。当前值:'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 的 init 在更改路由时比组件 1 的销毁更快。因此,组件 1 在销毁之前获取由组件 2 日期更改发起的更改(filteredBookings)。但这应该不是问题?

服务:

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);
}

【问题讨论】:

    标签: angular rxjs


    【解决方案1】:

    您使用的是 Angular 6 吗?

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

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

    我认为我们可以通过从组件订阅 observable 并将值传递给 view 来解决,但这不是一个好方法。

    You can check other way at here


    更新: 就我而言,我将 changeDetectionStrategyDefault 更改为 OnPush 它解决了我的问题。

    【讨论】:

      猜你喜欢
      • 2019-08-06
      • 1970-01-01
      • 2018-03-24
      • 1970-01-01
      • 2018-05-05
      • 1970-01-01
      • 1970-01-01
      • 2013-08-01
      • 2021-09-16
      相关资源
      最近更新 更多