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

Ido*_*Ido 13 typescript angular

使用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);
                }
            });
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

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

Thi*_*ier 22

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

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

constructor(private differs:  KeyValueDiffers) {
}

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

在其中ngDoCheck,您需要迭代differs以检查是否有更改(对于数组的每个项目):

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();
        }
      });
    }
  });
}
Run Code Online (Sandbox Code Playgroud)

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

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

  • 你想要将它设置为null以外的任何东西吗? (4认同)
  • 当elt是一个对象时,你怎么能在循环中写这行`this.objDiffer [elt]`,对于每次迭代,elt.toString()将等于[Object,Object]所以对于每次迭代,你都会得到相同的结果. (4认同)