我有一个项目数组,在显示之前,我使用了自定义管道转换函数来像这样向用户修改显示的数据:
`
<mat-chip
[removable]="true"
(removed)="onRemoveImage(storeImage)"
*ngFor="let storeImage of storeImages | storeImageView">{{ storeImage.name }}
<mat-icon matChipRemove>cancel</mat-icon>
</mat-chip>
`
storeImageView管道转换函数简单地获取数组,遍历其所有对象,创建对象的副本,然后在这些副本上转换name属性以在UI中显示。
管道功能: `
transform(storeImages: StoreImage[]): StoreImage[] {
let viewImagesArr: StoreImage[] = [];
for (let index = 0; index < storeImages.length; index++) {
let viewImage = Object.assign({}, storeImages[index]);
viewImage.name = viewImage.name = viewImage.name.slice(0, 4) + viewImage.ID.slice(0, 4);
viewImagesArr = [...viewImagesArr, viewImage];
}
return viewImagesArr;
}
`
如果用户将两个项目添加到数组中,则它们在DOM中都可以正常显示。用户一旦删除项目,就会触发remove函数并从数组中删除该项目,但是DOM不会更新。当我在HTML模板中取出管道运算符并且不转换输出时,所有输出均按预期工作。知道为什么吗?
答案 0 :(得分:1)
之所以发生这种情况,是因为您的管道是pure
管道,或者使之不纯。或者,当您从数组中删除项目时,请更改数组的引用。
@Pipe({ name: 'pipeName', pure: false})
this.storeImages = [...this.storeImages ]
,我认为这样做是一种性能更好的方法。答案 1 :(得分:0)
管道是纯函数。 管道的变化检测仅在存在参考变化时才运行,因为它遵循不变性的思想。 您正在使用一个基本上是对象的数组,并且在对象引用发生更改时对对象进行更改检测
因此,如果您需要在删除时反映更改,请更改数组的引用。
oldArray = [...]; // this is the array that has data
onDelete(itemToBeDeteled/index){
// if index is there then
oldArray = [].concat[oldArray.splice(index,1)];// ***shallow cloning of arrays***
// if item is present
// Your logic based on the item and create a new array after that and assign it to the array that is referenced in HTML.
}
如果该项是oldArray内的一个数组,那么我们需要执行深度克隆。
这是使用角管的一种干净方法。因为更改检测不会一次又一次地运行。其他方法是使用不纯的管,这会降低性能。