2016-03-02 26 views
7

Sử dụng Angular 2 và typescript. Tôi có một mảng mà tôi sử dụng DoCheck và IterableDiffer để nghe những thay đổi trong mã của tôi. Khi mảng được thay đổi, tôi nhận được thông báo, nhưng khi một thuộc tính bên trong một trong các đối tượng trong mảng thay đổi, tôi không được thông báo. Tôi đã thử sử dụng KeyValueDiffer nhưng nó không hoạt động. Tôi nghĩ có lẽ tôi cần sử dụng "_differs.find" khác nhau. Bất kỳ ý tưởng nào?Phát hiện các thay đổi trong các đối tượng bên trong mảng trong 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); 
       } 
      }); 
    } 
    } 
} 

Không có cách nào để nhận được thông báo về những thay đổi trong một trong những thuộc tính của myItem

+2

Bạn có thể cung cấp một số mã để hiển thị những gì bạn đã thử không? Cảm ơn! –

Trả lời

14

Trong thực tế, bạn cần phải kiểm tra sự khác biệt cho từng đối tượng trong danh sách không có tên trong danh sách riêng của mình. KeyValueDiffer phải được áp dụng trên một đối tượng không phải trên một mảng.

Bạn có thể khởi tạo một đối tượng chứa tất cả những KeyValueDiffer trường cho các phần tử của mảng của bạn:

constructor(private differs: KeyValueDiffers) { 
} 

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

Trong ngDoCheck, bạn cần sau đó để lặp qua các differ s để kiểm tra có sự thay đổi (đối với từng hạng mục của mảng):

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

Xem plunkr này: http://plnkr.co/edit/JV7xcMhAuupnSdwrd8XB?p=preview

Lưu ý rằng tôi đã bỏ qua phát hiện thay đổi cho mảng ... Nhưng cả hai có thể được thực hiện song song. Hơn nữa khi các phần tử được thêm/xóa danh sách KeyValueDiffers phải được cập nhật tương ứng.

+0

Phần '.create (null)' thực sự là gì? – Chrillewoodz

+1

Nó khởi tạo đối tượng khác với null. Vì vậy, phương thức 'diff' có thể xác định sự khác biệt đầu tiên (đối tượng hoàn chỉnh thực sự) ... –

+4

Bạn có bao giờ muốn đặt điều này thành bất kỳ thứ gì khác ngoài null không? – Chrillewoodz

Các vấn đề liên quan