什么是Angular不纯的管道?

Mr_*_*ect 41 angular-pipe angular

@Pipe({name:'myPipe', pure: false})
Run Code Online (Sandbox Code Playgroud)

我无法理解不纯净的管道,有些用纯管道更好.

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

Gün*_*uer 56

仅当Angular检测到值的更改或传递给管道的参数时,才会调用纯管道.无论值或参数是否发生变化,每个变化检测周期都会调用一个不纯的管道.

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

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

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

您应该意识到不纯的管道容易低效.例如,当一个数组被传递到管道中进行过滤,排序,......那么这项工作可能会在每次更改检测运行时完成(这通常特别是使用默认ChangeDetectionStrategy设置)事件,尽管数组甚至可能没有更改.你的管道应该尝试识别这个,例如返回缓存的结果.

  • 不纯的管道也是如此,但它的`transform()`方法被更频繁地调用.如果`{xxx |中的`xxx` 过滤}}`是一个数组,一个项目被添加或删除,然后一个纯管道将不会被调用,因为Angular不会将`xxx`识别为已更改,因为它是相同的`xxx`(虽然有不同的内容).如果你把它变成'pure:false`那么Angular2并不关心`xxx`是否已经改变,每次执行更改检测时它都会调用`transform()`. (13认同)
  • 你可以用一个例子来解释我吗? (2认同)
  • 实例演示到底是什么?http://stackoverflow.com/a/37828164/217408显示了过滤器管道(但没有缓存) (2认同)

Dac*_*ian 30

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

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

<p> {{'Hello' | translate }}<p>
<p> {{'World' | translate }}<p>
Run Code Online (Sandbox Code Playgroud)
  • 如果管道是纯的:只有一个管道实例.transform方法将在同一个实例上调用两次.
  • 如果管道是不纯的:将有两个管道实例.

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

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

OBS:这在我的角度4.0环境中有效.


Was*_*siF 7

演示:黑白纯净管和不纯管的区别

在中angular,a pipe可以用作pureimpure

什么是纯管或不纯管?

简而言之,仅在加载时,
impure-pipe作品中的每个更改都component
pure-pipe适用component

如何制作烟斗或不纯的烟斗?

@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
  }

}
Run Code Online (Sandbox Code Playgroud)

如何使用它?

<div> {{ arrayOfElements | sort }}<div>
Run Code Online (Sandbox Code Playgroud)

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

深入阅读纯净与不纯净管

  • 很好的答案,我正在寻找这种类型的答案,并提供很好的样本,非常感谢 (2认同)
  • 我对你的第二点表示怀疑,“纯管道仅在加载组件时才起作用”,而纯管道仅在传递给它的参数发生变化时才起作用,而不仅仅是在组件加载时。供您参考,您可以在这里查看 https://stackblitz.com/edit/pure-impure-pipe (2认同)

Rit*_*pta 5

纯和不纯管道

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

    • 纯更改是对原始输入(字符串、数字等)值的更改。或更改对象引用。
  • 默认情况下,管道是纯管道。

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

使管道不纯:

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

  transform(employees: Employee[], searchValue?: string): Employee[] {

   }
}
Run Code Online (Sandbox Code Playgroud)
<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> 
Run Code Online (Sandbox Code Playgroud)
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.
Run Code Online (Sandbox Code Playgroud)


Pra*_*ato 5

“纯管道”:

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

“不纯管道”:

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

不纯管道的示例

A。异步管道

b. 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);
  }
}
Run Code Online (Sandbox Code Playgroud)

.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>

Run Code Online (Sandbox Code Playgroud)