UI中不应该发生的纯管道更新数组



我在Angular中探索了Pipe函数,并了解到对于数组等非基本数据类型,即使数组元素发生了变化,Pipe函数也不会应用于更新后的数组,而是应用于初始数组本身。这就是为什么在添加新元素时,不向数组的新元素添加管道函数的原因。

但是当我尝试删除,添加和更新一个数组的管道函数的现有元素,它工作。然而,数组的变化不应该反映到UI中,因为管道函数是一个纯管道函数。请告诉我为什么当管道是纯管道时,数组的变化会被反映出来。

管道。TS:

import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
name: 'arrayPipe',
// pure:false
})
export class ArrayPipePipe implements PipeTransform {
transform(value: number[]) {
value.pop();
value.push(4);
value[1]=5;
console.log(value);
return (value);
}
} 

app.HTML:

<div>{{trialArray}}</div>
<div>{{trialArray | arrayPipe }}</div>

app.component.TS:

import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
trialArray = [1,2,3];
}

问题:当Angular知道"某事"改变吗?

回答:当他的值改变

数组(和对象)的问题是,当改变它的一些值(或一些属性)时,它不会改变,否则如果改变"在内存中的位置"。这就是您需要"创建一个新数组"的原因。一般使用展开运算符

this.trialArray=[...this.trialArray] //the ... are the spread operator

这是因为使用管道来转换数组(即使是管道排序)不是一个好方法

在stackblitz中注释

this.trialArray=[...this.trialArray]

你不能正确地看到数组

当然你可以创建一个"非"管道。当你声明管道时,你写pure:false

@Pipe({
name: 'arrayPipe',pure:false //<--see the "pure:false"
})
export class ArrayPipe implements PipeTransform{
transform(value: any[], args?: any): any {
return value.map((x) => x * 2);
}
}

这使得您可以"更改"。创建数组(无需创建副本)并显示结果。但这里。html中的数组没有更新

<div>{{trialArray}}</div>  //<--this show always [1,2,3]
<div>{{trialArray | arrayPipe }}</div>  //<--this change when "click"
click(){
this.trialArray.push(4);
}
在这种情况下,管道将在每个更改检测周期中调用,即使参数没有更改。",请参阅文档。

我们可以看到在transform

函数中添加了console.log("here")关于管道在这个问题中有两个问题

  1. 改变数组的值。我们可以解决在我们之前做一份副本可以使用sprred操作符

    export class ArrayPipe implements PipeTransform {
    transform(value: any[], args?: any): any {
    const result=[...value] //make a copy
    result.pop();   //change the copy
    result.push(4);
    result[1]=5;
    return result
    }
    }
    
  2. 如果我们愿意,我们可以将管道转换为不纯的,加入pure:false当创建

最新更新