Angular 入门基础(第七篇) 如何自定义Pipe(管道)

414 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第7天。点击查看活动详情

什么是管道

管道是在模板表达式中使用的简单函数,用于接受输入值并返回转换后的值。管道很有用,因为你可以在整个应用程序中使用它们,同时每个管道只声明一次。

内置管道

Angular 为典型的数据转换提供了内置的管道,包括国际化的转换(i18n),它使用本地化信息来格式化数据。数据格式化常用的内置管道如下:

  • DatePipe:根据本地环境中的规则格式化日期值。

要以当前语言环境的格式显示当前日期,请对 DatePipe 使用以下格式。

{{ today | date }}
  • UpperCasePipe:把文本全部转换成大写。
{{ value_expression | uppercase }}
  • LowerCasePipe :把文本全部转换成小写。
{{ value_expression | lowercase }}
  • CurrencyPipe :把数字转换成货币字符串,根据本地环境中的规则进行格式化。
{{ amount | currency : 'en-US' }}
  • DecimalPipe:把数字转换成带小数点的字符串,根据本地环境中的规则进行格式化。
{3.6 | number: '1.0-0'}}
<!--will output '4'-->
  • PercentPipe :把数字转换成百分比字符串,根据本地环境中的规则进行格式化。
 <!--output '26%'-->
 {{0.259 | percent}}
  • AsyncPipe : 从一个异步回执中解出一个值。
@Component({
  selector: 'async-promise-pipe',
  template: `<div>
    <code>promise|async</code>:
    <button (click)="clicked()">{{ arrived ? 'Reset' : 'Resolve' }}</button>
    <span>Wait for it... {{ greeting | async }}</span>
  </div>`
})
export class AsyncPromisePipeComponent {
  greeting: Promise<string>|null = null;
  arrived: boolean = false;

  private resolve: Function|null = null;

  constructor() {
    this.reset();
  }

  reset() {
    this.arrived = false;
    this.greeting = new Promise<string>((resolve, reject) => {
      this.resolve = resolve;
    });
  }

  clicked() {
    if (this.arrived) {
      this.reset();
    } else {
      this.resolve!('hi there!');
      this.arrived = true;
    }
  }
}
  • JsonPipe : 把一个值转换成 JSON 字符串格式。在调试时很有用。
{{ value_expression | json }}
  • SlicePipe: 从一个 Array 或 String 中创建其元素一个新子集(slice)。
{{ value_expression | slice : start [ : end ] }}
  • TitleCasePipe :把文本转换成标题形式。 把每个单词的第一个字母转成大写形式,并把单词的其余部分转成小写形式。 单词之间用任意空白字符进行分隔,比如空格、Tab 或换行符。
{{ value_expression | titlecase }}
  • KeyValuePipe: 将 Object 或 Map 转换为键值对数组。
@Component({
  selector: 'keyvalue-pipe',
  template: `<span>
    <p>Object</p>
    <div *ngFor="let item of object | keyvalue">
      {{item.key}}:{{item.value}}
    </div>
    <p>Map</p>
    <div *ngFor="let item of map | keyvalue">
      {{item.key}}:{{item.value}}
    </div>
  </span>`
})
export class KeyValuePipeComponent {
  object: {[key: number]: string} = {2: 'foo', 1: 'bar'};
  map = new Map([[2, 'foo'], [1, 'bar']]);
}

管道的优先级

管道操作符要比三目运算符(?:)的优先级高,这意味着 a ? b : c | x 会被解析成 a ? b : (c | x)。

由于这种优先级设定,如果你要用管道处理三目元算符的结果,就要把整个表达式包裹在括号中,比如 (a ? b : c) | x。

自定义管道

管道的作用就是将原始值进行转化处理,转换为所需要的值

ng g pipe sex
  • PipeTransform

一个需要由管道实现的接口,用于执行转换操作。 Angular 会调用它的 transform 方法,并把要绑定的值作为第一个参数传入,其它参数会依次从第二个参数的位置开始传入。

interface PipeTransform {
  transform(value: any, ...args: any[]): any
}
  • 引入PipeTransform是为了继承transform方法

  • name属性值惯用小驼峰是写法, name的值为html中| 后面的名称

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

@Pipe({ name: 'sex' })
export class SexPipe implements PipeTransform {
  transform(value: unknown, ...args: unknown[]): unknown {
    if (value === 0) {
      return '女';
    }
    return '男';
  }
}
<div>{{ 0 | sex }}</div>
<!-- 女 -->