【问题标题】:Pure Pipes in AngularAngular 中的纯管道
【发布时间】:2019-03-04 19:36:27
【问题描述】:

作为 Angular 的初学者,我遇到了纯管道

  • a) 仅在检测到输入值发生纯粹更改时执行。
  • b) 纯粹的更改是对原始输入值的更改
    (字符串、数字、布尔值)或更改的对象引用(数组、日期、 函数、对象)。
  • c) 如果管道的输入是纯管道,则不执行纯管道 对象,并且只有该对象的属性值会更改,但不会更改 参考。

我很清楚对象引用部分,问题在于原始类型。

一个关键的事实在于使用纯管道进行优化

Angular 只有在收到与之前调用不同的参数时才会评估给定的纯管道调用。

我尝试了一个例子:

applypure.pipe.ts

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

@Pipe({
  name: 'applypure',
  pure: true 
})
export class ApplypurePipe implements PipeTransform {
  count = 0;
  constructor() {
    // To determine an instance is created
    console.log('pipe created:');
  }

    transform(value: number, exponent: number): number {
    //this.count++;
    console.log(value);
    return Math.pow(value, exponent);;
  }
}

app.component.ts

import { Component } from '@angular/core';    

@Component({
  selector: 'my-app',
  template: `
            {{12 | applypure : 2}}
            {{12 | applypure: 2 }}  
           `
})
export class AppComponent  {
  }     
}

结果如下图:

相同的输入被立即传递给纯管道,但它的变换方法被调用了两次。它不应该跳过重新评估吗?请澄清。

【问题讨论】:

  • 状态pure 是每个管道。它与传入的值有关,如果您多次使用该管道,则不会重用。它在a) 中这么说。
  • @Silvermind;你能详细说明一下(一个例子)吗?
  • @jason 如果您查看日志管道仅创建一次并且在管道处理相同输入时重复使用相同的管道,则将根据管道使用情况调用转换
  • @Vishnu:管道实例的创建和执行是不同的 IMO。
  • @Jason,纯管道会记住上次输入以进行更改检测。

标签: angular angular-pipe


【解决方案1】:

管道之间没有共享的“缓存”。 “缓存”适用于模板中的每个调用

【讨论】:

  • 它只是一个管道,并且创建了一个实例。
  • 实际上每次在模板中调用它时都会创建一个实例
  • 但是日志没有这么说!
  • 你是对的,因为管道是无状态的,每次模板调用创建一个实例是没有意义的。我编辑我的答案
【解决方案2】:

我想我找到了正确的表达式!。

a) 使共享/缓存工作我相信组件中的表达式应该只有一个管道使用。对于立即相同的输入,纯管道的变换函数不会重新评估。

例如。当您输入 12 并回车时,将调用 transform fn,如果您立即再次输入 12,则会跳过对 transform fn 的调用。

因此,在 Pure Pipes 中,将检查管道表达式的最后一个输入,与紧邻的下一个输入相比,它是运行有效更改检测的标准。

app.component.html

    Type:
<input type="text" #box (keyup.enter)="addName(box.value); box.value=''" placeholder="Parameter"> 
  <div *ngIf="number2">
  {{number2 | applypure : 2}} 
</div>

app.component.ts

import { Component } from '@angular/core';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html'
})
export class AppComponent  {
  number2: number;

  addName(num: number) {
    this.number2 = num;
    console.log("Log at component: "+ this.number2);
  }

}

在第一次输入 12 之后

在第二次输入 12 之后

【讨论】:

    【解决方案3】:

    我相信这种情况正在发生,因为每次您在 HTML 中使用管道时,它都会调用转换函数。根据 Angular 存储库中的 PipeTransform 接口,管道在传递给其函数的属性之间没有区别:

    Angular 使用绑定的值调用 transform 方法 作为第一个参数,任何参数作为列表形式的第二个参数。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-01-10
      • 2018-11-27
      • 1970-01-01
      • 2016-07-20
      • 2021-03-27
      • 1970-01-01
      • 1970-01-01
      • 2017-01-16
      相关资源
      最近更新 更多