簡體   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