手动触发管道更新

时间:2017-05-05 08:04:52

标签: angular angular-pipe

我创建了一个能够使用*ngFor with objects的管道。但是,更新对象时,管道不会更新。我通过使用带有pure: false的有状态管道找到了解决方案here

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

有没有办法触发手动刷新管道,只有在我需要时才刷新?

以下是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 个答案:

答案 0 :(得分:10)

使 Pure Pipe 变为不纯的一种方法是向parameter添加Pipe

当您想要刷新时,只需更改参数。

没有参数的另一种方式:

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

let copy = { ...original }

这两种方式都包含在 stackbliz demo

答案 1 :(得分:0)

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

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

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

this.elements.remove(0);

您可以通过将this.elements替换为新版本来对其进行更新:

this.elements = this.elements.splice(0, 1);

答案 2 :(得分:0)

我从上方拿起了Pengyy的解决方案,并用它制成了烟斗:

@Pipe({
  name: 'refresh'
})
export class RefreshPipe implements PipeTransform {

  transform(value: any, refreshValue?: any): any {
    if (value == null) {
      return null;
    }
    return JSON.parse(JSON.stringify(value));
  }

}

用法:

*ngFor="let key of keys | refresh:refreshCount | keys"

当需要刷新时,在组件类中递增refreshCount:

this.refreshCount++

此解决方案保留了在本地刷新到组件并且不在数据范围或其他管道范围之外的逻辑。否则,使用不可变对象可能会以不同的方式解决此问题。

答案 3 :(得分:0)

创建管道,以下是两种解决方法:

1,但是这种方式会触发很多次,这对您的网站不利。
@Pipe({ name: 'tablepipe', pure: false })

2。使用ngModel +纯管道

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

this.detectedChangeRef = Math.random();

您的html,因为管道会注意到您的引用的更改,因此会触发管道:

* ngFor =“让item | tablepipe:detectedChangeRef;”>

您的烟斗

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

}