Detect changes in objects inside array in Angular2

后端 未结 2 689
轻奢々
轻奢々 2020-11-30 04:29

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 whe

相关标签:
2条回答
  • 2020-11-30 04:59

    I found inspiration in Thierry Templiers answer but it did not work for me- I modified it and ended up with this solution:

    You have this private variable:

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

    You want to watch each element in an Array. In this case the array type is Array. The constructor should look like this:

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

    ngOninit like this:

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

    and ngDoCheck like this:

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

    Now you will notice that each time an item within the array changes you will get a console log with that item and with the property that has changed.

    0 讨论(0)
  • 2020-11-30 05:02

    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.

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

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

    See this plunkr: http://plnkr.co/edit/JV7xcMhAuupnSdwrd8XB?p=preview

    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.

    0 讨论(0)
提交回复
热议问题