繁体   English   中英

检测Angular2中数组内对象的更改

[英]Detect changes in objects inside array in Angular2

使用Angular 2和打字稿。 我有一个数组,我使用DoCheck和IterableDiffer来监听我的代码中的更改。 当数组被更改时,我收到通知,但是当数组中某个对象内的属性发生更改时,我不会收到通知。 我尝试使用KeyValueDiffer,但它不起作用。 我想也许我需要以不同方式使用“_differs.find”。 有任何想法吗?

@Component({
    selector: 'test'
})
@View({
    template: `
    <div>hello!</div>`
})
export class MyComponent implements DoCheck {

private _differ: IterableDiffer;
private _differ2: KeyValueDiffer;
_myItems: MyItem[];
@Input()
set myItems(value: MyItem[]) {
    this._myItems = value;

    if (!this._differ && value) {
        this._differ = this._iterableDiffers.find([]).create(null);
    }
    if (!this._differ2 && value) {
        this._differ2 = this._differs.find(this._myItems).create(null);
    }
}
get myItems() {
    return this._myItems;
}

constructor(private _iterableDiffers: IterableDiffers, private _differs: KeyValueDiffers, private _myService: MyService) {
    this.myItems = _myService.getItems();
}

ngDoCheck() {

    var changes = this._differ.diff(this._myItems);

    if (changes) {
        changes.forEachAddedItem((record) => {
            console.log('added ' + record.item);
        });
        changes.forEachRemovedItem((record) => {
            console.log('removed ' + record.item);
        });
    }

    var changes2 = this._differ2.diff(this._myItems);
    if (changes2) {
        changes2.forEachChangedItem(
            (record) => {
                    console.log(record.key + "," + record.currentValue);
                }
            });
    }
  }
}

无法获得有关MyItem的某个属性更改的通知

实际上,您需要检查列表中每个对象的差异,而不是列表本身。 KeyValueDiffer必须应用于不在数组上的对象。

您可以初始化包含阵列元素的所有KeyValueDiffer实例的对象:

constructor(private differs:  KeyValueDiffers) {
}

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

ngDoCheck ,您需要迭代differ s来检查是否有更改(对于数组的每个项目):

ngDoCheck() {
  this.list.forEach(elt => {
    var objDiffer = this.objDiffer[elt];
    var objChanges = objDiffer.diff(elt);
    if (objChanges) {
      objChanges.forEachChangedItem((elt) => {
        if (elt.key === 'prop1') {
          this.doSomethingIfProp1Change();
        }
      });
    }
  });
}

看到这个plunkr: http ://plnkr.co/edit/JV7xcMhAuupnSdwrd8XB?p = preview

请注意,我跳过了数组的更改检测...但两者都可以并行完成。 此外,当添加/删除元素时,应相应地更新KeyValueDiffers列表。

我在Thierry Templiers的答案中找到了灵感,但它对我没有用 - 我修改了它并最终得到了这个解决方案:

你有这个私有变量:

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

您想要观察数组中的每个元素。 在这种情况下,数组类型是Array。 构造函数应如下所示:

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

像这样的ngOninit:

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

和ngDoCheck像这样:

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

现在您将注意到,每次数组中的项目发生更改时,您将获得包含该项目的控制台日志以及已更改的属性。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM