检测输入数组对象的变化

时间:2019-11-06 16:33:27

标签: angular typescript

我正在尝试获取Angular组件Input变量以检测更改。输入变量是一个对象数组,我需要检测哪些对象发生了变化以及哪些属性正在发生变化。我正在使用它来更改父组件中子组件中表单控件的行为。

我尝试了以下解决方案:

Detect changes in objects inside array in Angular2

constructor(private differs:  KeyValueDiffers) {
}

ngOnInit() {
  this.objDiffer = {};
  this.list.forEach((elt) => {
    this.objDiffer[elt] = this.differs.find(elt).create(null);
  });
}

但是.create函数需要TrackByFunction,并且无法分配this.objDiffer [elt],因为它是对象而不是对象列表。

Detect changes in objects inside array in Angular2

 private objDiffers: Array<KeyValueDiffer<string, any>>;

  constructor(
    private differs: KeyValueDiffers) {
    this.itemGroups = new Array<ItemGroup>();
    this.differ = this.differs.find(this.itemGroups).create();
  }

  public ngOnInit(): void {
    this.objDiffers = new Array<KeyValueDiffer<string, any>>();
    this.itemGroups.forEach((itemGroup, index) => {
      this.objDiffers[index] = this.differs.find(itemGroup).create();
    });
  }

ngDoCheck(): void {
    this.itemGroups.forEach((itemGroup, index) => {
      const objDiffer = this.objDiffers[index];
      const objChanges = objDiffer.diff(itemGroup);
      if (objChanges) {
        objChanges.forEachChangedItem((changedItem) => {
          console.log(changedItem.key);
        });
      }
    });
  }

这让我改变了值,但没有改变我要寻找的实际对象。

http://blog.bogdancarpean.com/how-to-watch-for-changes-an-arrayobject-on-angular-2/

export class ArrayWatchDemoComponent implements DoCheck {

  @Input() datasource: Array&lt;any&gt; = [];

  differ: any;

  constructor(differs: IterableDiffers) {
     this.differ = differs.find([]).create(null);
   }

  ngDoCheck() {
    const change = this.differ.diff(this.datasource);
    console.log(change);
  }

此解决方案仅是控制台记录空值的控制台。但是,当我更改输入数组中对象的属性时,它将触发。我知道您可以使用forEachAddedItem或forEachRemovedItem,但这不能解决问题。

https://www.concretepage.com/angular/angular-keyvaluediffers

@Input() empArray: Employee[];
empDifferMap = new Map<number, any>();
empMap = new Map<number, Employee>();
arrayDiffer: any;
constructor(private kvDiffers: KeyValueDiffers) {}
ngOnInit() {
    this.empArray.forEach(emp => {
      this.empDifferMap[emp.id] = this.kvDiffers.find(emp).create();
      this.empMap[emp.id] = emp;
    })
}
ngDoCheck() {
    for (let [key, empDiffer] of this.empDifferMap) {
      let empChanges = empDiffer.diff(this.empMap.get(key));
      if (empChanges) {
        empChanges.forEachChangedItem(record => {
          console.log('Previous value: ' + record.previousValue);
          console.log('Current value: ' + record.currentValue);
        });
      }
    }
} 

这是我尝试过的最新版本,但是我没有使它正常工作并出现错误

  

“ src / app / forms / dynamic-form / dynamic-form.component.ts(39,34)中的错误:   错误TS2569:类型“映射”不是数组类型或字符串   类型。使用编译器选项'--downlevelIteration'允许迭代   迭代器。”

我也尝试过再次创建数组。

//this.list = [{foo: true}];
this.list = [];
this.list = [{foo: false}];

但这是一个丑陋的解决方案,并使子组件中的元素闪烁。

我希望子组件能够检测到作为输入数组的对象中的更改。 子组件无法检测到更改。

1 个答案:

答案 0 :(得分:0)

我强烈建议用户使用FormArray窗体Angular Reactive Forms。 FormArray也是一种检测更改的高效方法。查找此链接开始 FormArray starter