25

我创建了一个能够*ngFor与对象一起使用的管道。但是,当对象更新时,管道不会更新。我在这里找到了一个解决方案,方法是使用带有pure: false.

这个解决方案在我的用例的性能方面是不可接受的,因为它会为每次更改刷新管道(我几乎在任何地方都使用这个管道来渲染复杂的元素)。

有没有办法触发管道的手动刷新,所以它只在我想要的时候刷新?

这是一个plunker - 要查看问题,请尝试通过单击-按钮来删除名称。如果添加pure:false,您将看到它将起作用:

@Pipe({name: 'keys', pure: false})
export class Keys implements PipeTransform {
  transform(value, args:string[]) : any {
    let keys = [];
    for (let key in value) {
      keys.push({key: key, value: value[key]});
    }
    return keys;
  }
}

我想要的是在我的delName()函数中添加一些东西,以便它更新管道......

4

3 回答 3

29

第一种方式:参数

使Pure Pipe变得不纯的一种方法是parameter在您的Pipe.

当你想刷新时,只需更改参数即可。


第二种方式:无参数

Pure Pipe 将在其输入具有新实例时被触发。因此,对于 TypeScript 2.1+,下面的代码将使用新实例复制原始对象,并引导纯管道被触发。

    let copy = { ...original }

负面影响

这将强制您的组件在每次变量更改其值时刷新您的管道,即使这不是管道中使用的包含


堆栈闪电战

两种方式都包含在stackbliz 演示中。

于 2017-05-05T08:16:59.580 回答
2

带有输入对象的纯管道仅在对象的引用更改时才会发出更新。

如果您能找到一种方法在对象的部分结构发生更改时将其替换为新实例,那么纯管道将根据需要自动更新其输出。

假设您现有的delName函数只是从现有结构中删除一个元素:

this.elements.remove(0);

您可以通过替换this.elements为新版本来更新它:

this.elements = this.elements.splice(1);
于 2018-09-18T08:39:34.693 回答
1

创建管道,这里有两种解决方法:

1,但是这种方式会触发多次,对你的网站不利。

   @Pipe({
  name: 'tablepipe',
  pure: false
})

2.使用 ngModel + 纯管道

    <input 
                style="position: absolute;
                z-index: -1;"
                [(ngModel)]="detectedChangeRef">
this.detectedChangeRef = Math.random();

你的 html,因为管道会注意到你的 ref 的变化,它会触发你的管道:


   *ngFor="let item1 of item | tablepipe:detectedChangeRef;">

你的管道

     transform(value,detectedChangeRef) {
    console.log(detectedChangeRef);
     // do sth..
}

于 2020-10-22T02:15:09.060 回答