检测Angular2中数组内部对象的变化 [英] Detect changes in objects inside array in Angular2

查看:107
本文介绍了检测Angular2中数组内部对象的变化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用Angular 2和打字稿.我有一个数组,可以使用DoCheck和IterableDiffer来侦听代码中的更改.当数组更改时,我会收到通知,但是当数组中的一个对象内部的属性发生更改时,我不会收到通知. 我尝试使用KeyValueDiffer,但是它不起作用. 我认为也许我需要以不同的方式使用"_differs.find". 有什么想法吗?

Using Angular 2 and typescript. I have an array that I use DoCheck and IterableDiffer to listen to changes in my code. When the array is changed I get notifications, but when a property inside one of the objects in the array changes I don't get notified. I tried using KeyValueDiffer but it doesn't work. I think maybe I need to use the "_differs.find" differently. Any ideas?

@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属性之一的更改的通知

There is no way to get notified on changes in one of the properties of MyItem

推荐答案

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

In fact, you need to check differences for each object in the list not on the list itself. KeyValueDiffer must be applied on an object not on an array.

您可以初始化一个对象,其中包含数组元素的所有这些KeyValueDiffer实例:

You could initialize an object containing all these KeyValueDiffer instances for the elements of your array:

constructor(private differs:  KeyValueDiffers) {
}

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

ngDoCheck内,您需要遍历differ s以检查是否有更改(对于数组的每个项目):

Within the ngDoCheck, you need then to iterate over the differs to check there are changes (for each item of the array):

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

请参阅以下代码: http://plnkr.co/edit/JV7xcMhAuupnSdwrd8XB?p=preview

请注意,我跳过了对阵列的更改检测...但是两者可以并行完成.此外,在添加/删除元素时,KeyValueDiffers的列表应进行相应的更新.

Notice that I skipped the change detection for the array... But both can be done in parallel. Moreover when elements are added / removed the list of KeyValueDiffers should be updated accordingly.

这篇关于检测Angular2中数组内部对象的变化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆