使用自定义管道变换功能时,从属性绑定中删除数据不会反映在Angular的模板视图中

时间:2019-04-18 11:16:32

标签: angular

我有一个项目数组,在显示之前,我使用了自定义管道转换函数来像这样向用户修改显示的数据:

`
<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模板中取出管道运算符并且不转换输出时,所有输出均按预期工作。知道为什么吗?

2 个答案:

答案 0 :(得分:1)

之所以发生这种情况,是因为您的管道是pure管道,或者使之不纯。或者,当您从数组中删除项目时,请更改数组的引用。

  1. 使管道不纯:@Pipe({ name: 'pipeName', pure: false})

  1. 或者在执行删除操作后,执行以下操作: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内的一个数组,那么我们需要执行深度克隆。

这是使用角管的一种干净方法。因为更改检测不会一次又一次地运行。其他方法是使用不纯的管,这会降低性能。

https://angular.io/guide/pipes#pure-and-impure-pipes