2016-03-02 69 views
7

使用Angular 2和typescript。我有一個數組,我使用DoCheck和IterableDiffer來偵聽我的代碼中的更改。當數組發生變化時,我收到通知,但是當數組中的一個對象中的某個屬性發生更改時,我不會收到通知。 我嘗試過使用KeyValueDiffer,但它不起作用。 我想也許我需要以不同的方式使用「_differs.find」。 任何想法?檢測Angular2中陣列內物體的變化

@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

+2

你能提供一些代碼來展示你的嘗試嗎?謝謝! –

回答

14

的特性之一。事實上在改變通知,您需要檢查每個對象的差異未在列表列表本身上。 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列表。

+0

什麼是'.create(null)'部分實際上是做什麼的? – Chrillewoodz

+1

它用null初始化不同的對象。所以'diff'方法可以確定第一個區別(實際上是完整的對象)...... –

+4

你是否曾經想將它設置爲null以外的任何東西? – Chrillewoodz