【问题标题】:What is an impure pipe in Angular?Angular 中的不纯管道是什么?
【发布时间】:2017-01-10 03:58:33
【问题描述】:
@Pipe({name:'myPipe', pure: false})

我无法理解不纯的管道。

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

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

【问题讨论】:

标签: angular angular-pipe angular2-pipe


【解决方案1】:

纯管道仅在 Angular 检测到值或传递给管道的参数发生变化时调用。

不纯管道在每个变化检测周期都会被调用,无论值或参数是否发生变化。

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

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

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

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

【讨论】:

  • 你能举个例子解释一下吗?
  • 举例说明究竟是什么? stackoverflow.com/a/37828164/217408 显示一个过滤管道(但没有缓存)
  • 纯管道意味着,每次有人更改传递给它的输入时,它都会执行。例如,{{ 2 | exponent: var }}; <input [(ngModel)]="var"/>。现在,当我们更改输入 var 时,值就会更新。同样,请通过不纯管道更新我的值。任何人??这里exponent 是我的管道
  • 一个不纯的管道做同样的事情,但它的transform()方法被调用得更频繁。如果{{xxx | filter}} 中的xxx 是一个数组并且添加或删除了一个项目,则不会调用纯管道,因为Angular 无法将xxx 识别为已更改,因为它是相同的xxx(具有不同的虽然内容)。如果您将其设为pure: false,那么Angular2 并不关心xxx 是否已更改,它会在每次执行更改检测时调用transform()
  • @GünterZöchbauer 不纯管道与绑定函数有什么不同吗?我担心它们对性能的影响是否不同。
【解决方案2】:

除了上一个答案,我想补充另一个区别:实例数。

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

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

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

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

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

【讨论】:

    【解决方案3】:

    Demo: difference b/w pure and impure pipe

    angular中,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
      }
    
    }
    

    如何使用?

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

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

    Read in depth: Pure vs Impure Pipe

    【讨论】:

    • 很好的答案我一直在寻找这种类型的答案,非常感谢你
    • 我怀疑你的第二点pure-pipe works only when the component is loaded,而是纯管道仅在传递给它的参数发生变化时才起作用,而不仅仅是在组件加载时。供您参考,您可以在这里查看stackblitz.com/edit/pure-impure-pipe
    • @PardeepJain 你是对的,但使用的是 Angular 版本 8。如果看我的演示,它使用的是 Angular 版本 6,因此 Angular 版本 7 或 8 中的管道性能得到了改进。
    【解决方案4】:

    纯和不纯的管道

    • 纯管道是仅在“PURE CHANGE”到 检测到输入值。

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

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

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

    使管道不纯:

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

    【讨论】:

    【解决方案5】:

    “纯管道”:

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

    “不纯管道”:

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

    不纯管道示例

    一个。异步管道

    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);
      }
    }
    

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-11-27
      • 1970-01-01
      • 2016-07-20
      • 2018-07-18
      • 1970-01-01
      • 1970-01-01
      • 2019-04-11
      相关资源
      最近更新 更多