使用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
的某个属性的更改答案 0 :(得分:21)
实际上,您需要检查列表中不是列表本身的每个对象的差异。 KeyValueDiffer
必须应用于不在数组上的对象。
您可以为数组元素初始化包含所有这些KeyValueDiffer
实例的对象:
constructor(private differs: KeyValueDiffers) {
}
ngOnInit() {
this.objDiffer = {};
this.list.forEach((elt) => {
this.objDiffer[elt] = this.differs.find(elt).create(null);
});
}
在ngDoCheck
中,您需要迭代differ
以检查是否有更改(对于数组的每个项目):
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
列表应相应更新。
答案 1 :(得分:0)
我在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);
});
}
});
}
现在,您会注意到,每次数组中的一项发生更改时,您都会获得一个控制台日志,其中包含该项以及已更改的属性。