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

我无法理解不纯的管道。

纯水管和非纯水管有什么区别?

请用一个简单而基本的例子来解释。

4

5 回答 5

120

只有当 Angular 检测到值或传递给管道的参数发生变化时,才会调用纯管道。

无论值或参数是否更改,每个更改检测周期都会调用不纯管道。

这与 Angular 未检测到的更改有关

  • 当你传递一个改变了内容的数组或对象时(但仍然是同一个实例)
  • 当管道注入服务以访问其他值时,Angular 无法识别它们是否已更改。

在这些情况下,您可能仍然希望执行管道。

您应该知道,不纯的管道很容易效率低下。例如,当一个数组被传递到管道中进行过滤、排序……那么每次更改检测运行(这通常尤其是默认ChangeDetectionStrategy设置)事件时都可能完成这项工作,尽管数组甚至可能没有改变。您的管道应该尝试识别这一点,例如返回缓存的结果。

于 2016-09-02T06:26:11.230 回答
42

除了先前的答案,我想添加另一个区别:实例数。

假设在 HTML 代码中多次使用管道。喜欢:

<p> {{'Hello' | translate }}<p>
<p> {{'World' | translate }}<p>
  • 如果管道是纯的:将只有一个管道实例。transform 方法将被调用两次,但在同一个实例上。
  • 如果管道不纯:将有两个管道实例。

(您可以通过在管道的构造函数中生成一个随机 id 并在两者中打印它来看到这一点:constructortransform方法)

由于纯管道(或通常是纯函数)确实(不应该)有任何副作用,相同的纯代码可以重复使用任意次数而无需担心。似乎这就是为什么纯管道只实例化一次的原因。

OBS:这在我的 Angular 4.0 环境中有效。

于 2017-08-31T16:40:46.253 回答
29

演示:区分黑白纯和不纯管道

angular中,apipe可以用作pureimpure

什么是纯管道或不纯管道?

简而言之,只有在加载时才
impure-pipe适用于作品中的每一次更改。component
pure-pipecomponent

如何使管道或不纯的纯净?

@Pipe({
  name: 'sort',
  pure: false //true makes it pure and false makes it impure
})
export class myPipe implements PipeTransform {

  transform(value: any, args?: any): any {
     //your logic here and return the result
  }

}

如何使用它?

<div> {{ arrayOfElements | sort }}<div>

使用不纯管道时要小心,因为如果使用不当,可能会过度使用您的系统资源。

深入阅读:纯管道与非纯管道

于 2018-09-09T10:12:18.330 回答
7

纯和不纯的管道

  • 纯管道是仅在检测到输入值的“纯更改”时执行的管道。

  • 纯粹的更改是对原始输入(字符串、数字等)值的更改。或更改了对象引用。

  • 默认情况下,管道是纯管道。

  • 因此,不纯管道每次都会执行,而不管源是否已更改。这会导致性能不佳。这就是为什么不建议使用管道过滤数据的原因。

使管道不纯:

@Pipe({
  name: 'empFilter',
  pure: false  // default is set to true.
})
export class EmpFilterPipe implements PipeTransform {

  transform(employees: Employee[], searchValue?: string): Employee[] {
  
   }
}
<input type="text" [(ngModel)]="searchValue">
<button (click)="changeData()"></button>

changeData(): void{
    this.employees[0].name = "SOMETHING ELSE";
}

<div *ngFor="let emp of employees | empFilter : searchValue">
    {{emp.name}}
</div> 
NOTE : if pipe is pure and  employees data is changed using method "changeData()" - It will not detect the changes .
     Since input value to the  EmpFilterPipe is Object & reference of "employees"  has not been changed.
于 2019-02-10T09:59:54.877 回答
2

“纯管道”:

  1. 纯管道使用纯函数。只有当 Angular 检测到值或作为输入传递给管道的参数发生变化时才会调用它。纯管比不纯管有很多优点:
  2. 只有当传递的值或参数发生变化时,纯管道才会重新计算。
  3. 纯管道将缓存先前值或输入的结果。因此,纯管道可以绑定缓存中的输出,而无需重新评估输入是否更改。
  4. 纯管道的单个实例用于所有组件。
  5. 我们只需要根据已知的输入和输出对其进行测试。
  6. 纯管道评估为输入值(字符串、数字、布尔值)或对象引用(日期、数组、对象)中的纯变化。
  7. 在纯管道的情况下,输入不应该是可变的。

“不纯的管道”:

  1. Angular 中的每个变更检测周期都会调用不纯管道。无论输入或值的变化如何,它都会在每个摘要循环中调用。如果我们需要在每次更改检测时调用一些管道,请将管道标记为不纯。在不纯管道的情况下,Angular 将在每个更改周期调用 transform() 方法。
  2. 为不纯管道创建多个实例。
  3. 不纯的管道不会重复使用。
  4. 如果管道不纯,我们不能使用缓存。
  5. 取决于一些内部状态。
  6. 在每个更改检测周期调用。
  7. 传递给此管道的输入可以是可变的。

不纯管道示例

一个。异步管道

湾。JsonPipe 和 SlicePipe

.ts 文件

import { PipeTransform, Pipe } from '@angular/core';
import { User } from './User';

// Pipe
@Pipe({
  name: 'filter',
  pure: true    ----> 'Default is true'
})
export class FilterPipe implements PipeTransform {
  transform(users: User[], searchTerm: string): User[] {
    if (!users || !searchTerm) {
      return users;
    }
    return users.filter(user => user.name.toLowerCase()
      .indexOf(searchTerm.toLowerCase()) !== -1);
  }
}

.html 文件

<input type="text" [(ngModel)]="searchTerm"  placeholder="Enter name" >
<button (click)="changeProperty()">change by Property</button>
<button (click)="changeReference()">change by Reference</button>
<ul>
<li *ngFor="let user of users | filter:searchTerm">{{user.name}}  </li>
</ul>

于 2020-09-18T20:00:36.223 回答