使用 IterableDiffer 在 Angular 8 中获取数组大小变化

Get array size changes in Angular 8 using IterableDiffer

我有 angular 个带有对象数组的组件

export class AlertsConfigListComponent implements OnInit, DoCheck {
@Input() config: ProductAlertConfig[];

并使用 IterableDiffer 获取此数组的更改: constructor(private iterableDiffers: IterableDiffers) { this.iterableDiffer = iterableDiffers.find([]).create(null); }

ngDoCheck(): void {
let changes : IterableChanges<ProductAlertConfig> = this.iterableDiffer.diff(this.config);
if (changes) {
  this.doSmth();
}

}

它有效,每次更改数组时我都可以得到更改。 所以现在我的问题是。如何检查数组大小已更改的 changes 对象,因为当我对该数组进行排序时它也会被触发。 IterableChanges 对象中没有用于此目的的属性。

如果我可以获得新的数组大小,我会这样做:

ngDoCheck(): void {
let changes : IterableChanges<ProductAlertConfig> = this.iterableDiffer.diff(this.config);
if (changes && newSize !== oldSize) {
  this.doSmth();
}

}

它会解决问题,但还有其他解决方案吗?

问题出在你的构造函数上。

constructor(private iterableDiffers: IterableDiffers){
   this.iterableDiffer = iterableDiffers.find(this.config).create()
}

工作 Stackblitz :- https://stackblitz.com/edit/angular-uqivci

不知道有没有直接的方法。一种解决方法是通过滥用 forEachAddedItemforEachRemovedItem 方法以及 try/catch 块来检查数组中是否有元素 added/removed。尝试以下

ngDoCheck(): void {
  let changes: IterableChanges<ProductAlertConfig> = this.iterableDiffer.diff(this.config);
  let lengthChanged: boolean = false;

  if (changes) {
    try {
      changes.forEachAddedItem(item => {
        if (item) {
          lengthChanged = true;
          throw 'Array length changed';           // break from the `forEach`
        }
      });

      if (!lengthChanged) {                       // proceed only if `lengthChanged` is still `false`
        changes.forEachRemovedItem(item => {
          if (item) {
            lengthChanged = true;
            throw 'Array length changed';         // break from the `forEach`
          }
        });
      }
    } catch (e) {
      // pass
    }

    if (lengthChanged) {
      this.doSmth();
    }
  }
}

这里特意用

Try/catch来打破forEach。对此发表评论会有所帮助 others/later