美文网首页
Angular Pipe

Angular Pipe

作者: forks1990 | 来源:发表于2018-09-26 11:47 被阅读0次

Angular Pipe is object, not function, when pipe created, does or how it reused, lets find out by examples:

Pure Pipe

Pure Pipe means output depends only on input, if input not changed, pipe transmission function not called:

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

const idx = 0;

@Pipe({
  name: 'toInt'
})
export class ToIntPipe implements PipeTransform {
  id: string;

  constructor() {
    this.id = `idx-${idx}`;
    console.log(`Create ${this.id} instance`);
  }

  transform(value: number): any {
    console.log(`${this.id} transform ${value}`);
    return value.toFixed(1);
  }
}
<output>{{v1 | toInt}} {{v2 | toInt}}</output>
<button (click)="v1 = v1 + 1.17">Inc1</button>
<button (click)="v2 = v2 + 1.17">Inc2</button>

Here is the console output:

Create idx-0 instance
to-int.pipe.ts:17 idx-0 transform 3.13
to-int.pipe.ts:17 idx-0 transform 2.13
to-int.pipe.ts:17 idx-0 transform 5.47
to-int.pipe.ts:17 idx-0 transform 3.3
to-int.pipe.ts:17 idx-0 transform 4.47
  1. One toInt pipe instance created, serves for all two value bindings.
  2. As document says, if value not changed, the pipe not called, because it is pure.
    Changed means '===', for object/array, change content does not means change, create a new instance or use impure pipe.

Let's find out what happened if argument changed but not value. Add argument to ToIntPipe:

export class ToIntPipe implements PipeTransform {

  ...

  transform(value: number, digits: number = 1): any {
    console.log(`${this.id} transform ${value}`);
    return value.toFixed(digits);
  }

Update page template:

<output>{{v1 | toInt}} {{v2 | toInt:digits}}</output>
<button (click)="v1 = v1 + 1.17">Inc1</button>
<button (click)="v2 = v2 + 1.17">Inc2</button>
<button (click)="digits = digits ? 0 : 2">Toggle Digits</button>
import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'try-ngc';

  v1 = 3.13;
  v2 = 2.13;

  digits = 2;
}

Click toggle digits button, toggles digits 0/3, as expected, angular call transform() on argument changes.

Impure Stateful Pipe

Mark toInt pipe as pure: false:

@Pipe({
  name: 'toInt', pure: false,
})
export class ToIntPipe implements PipeTransform {

Here is the console log after web page reload:

to-int.pipe.ts:13 Create idx-1 instance
to-int.pipe.ts:13 Create idx-2 instance
to-int.pipe.ts:17 idx-1 transform 3.13
to-int.pipe.ts:17 idx-2 transform 2.13
to-int.pipe.ts:17 idx-1 transform 3.13
to-int.pipe.ts:17 idx-2 transform 2.13
core.js:3121 Angular is running in the development mode. Call enableProdMode() to enable the production mode.
to-int.pipe.ts:17 idx-1 transform 3.13
to-int.pipe.ts:17 idx-2 transform 2.13
to-int.pipe.ts:17 idx-1 transform 3.13
to-int.pipe.ts:17 idx-2 transform 2.13

  1. Each binding creates a toInt pipe instance,
  2. Without touch button, for each binding, toInt transform called four times.

Cache Expensive Transmission Result

Using pure pipe, because only one pure pipe object instance per template, can not save cache result inside pipe object, need some Cache Service:

@Injectable({
  providedIn: 'root'
})
export class CacheService {
  private _cache = new Map();

  get(key: string, Func1<string, any>) {
    ....
  }
}

@Pipe({
  name: 'toInt',
})
export class ExpensivePipe implements PipeTransform {

  constructor(private cache: CacheService) { }

  transform(value: string): any {
    return this.cache.get(value, expensiveTransform);
  }
}

On the other hand, impure service has an advantage: it is stateful, saves and caches transmission result easily inside pipe object instance.

Conclusion

  1. Angular shares pure pipe for all value bindings
  2. Impure pipe created for each value binding, instance not shared
  3. Impure pipe transform() method called much more frequently than pure pipe
  4. Pure pipe only called on: 1st render, value changes, argument changes.
  5. Impure pipe implement cache maybe more easier, but for best performance, pure pipe with CacheService is the best option.

相关文章

  • Angular Pipe

    Angular Pipe is object, not function, when pipe created, ...

  • Angular—pipe

    什么是pipe 中文释义“管道”。 把数据作为输入,然后转换它,给出期望的输出。例如,将UTC时间转为指定格式;中...

  • Angular 关于pipe

    Angular 中的管道其实就是angularjs中的过滤器,用来转换数据然后显示给用户。要创建一个管道,必须实现...

  • new Date(date)在ios下的兼容性问题。

    附上moment.js及Angular@Pipe相关链接: http://momentjs.cn/https://...

  • angular pipe 自定义管道

    可以理解为angular中的管道(pipe)与angular1.x的过滤器(filter)一样。 那么我们就来自定...

  • angular component direct pipe

    组件 声明一个组件 定义完组件需要在app.module declarations引入 cli创建组件 利用命令创...

  • Angular 单元测试实践 (4)

    本文继续介绍如何对 Angular 的管道(pipe)、指令(directive)和表单(form)进行单元测试。...

  • Angular component 组件内使用原生pipe

    Angular内置的pipe一般用在template中,比如下面的CurrencyPipe用来格式化货币 A: {...

  • Angular自定义pipe实现

    angular尽管内置许多的pipe,比如date、async、currency等。尽管拿来即用,但是远不能满足于...

  • angular2管道pipe

    谁用angular2自定义管道写过过滤器,搜索类似于angular1中firter的功能?急急

网友评论

      本文标题:Angular Pipe

      本文链接:https://www.haomeiwen.com/subject/jnldoftx.html