Angular8-自定义系列之管道

6次阅读

共计 2253 个字符,预计需要花费 6 分钟才能阅读完成。

管道

管道:(非官方释义)数据显示在模板上之前需要根据某些条件作出进一步处理,比如格式化等。可以理解为执行自定义的方法,参数为绑定的数据。

内置管道

Angular 内置十几种内置管道用于常规开发和调试,如转化为 json 的管道 json,使用示例:

{{obejct | json}}

还有时间格式转换的 date,英文词转小写的 lowercase 等。

对管道进行参数化

管道对数据处理时候可能还配置了多种 option 模式,如果要指定 option,得告诉这个管道,这个过程叫做管道参数化,例如:{{new Date() | data:’shortDate’}}

链式管道

多层管道处理,jquery 链式写法是‘.’;管道则是‘|’,{{new Date()|data|lowercase}}

<div>
  date:{{currentDate}}
  <ul>
    <li>
      使用 date 管道:{{currentDate|date}}
    </li>
    <li>
      使用参数化的 date: {{currentDate|date:'shortDate'}}
    </li>
    <li>
      使用链式管道 date、lowercase:{{currentDate|date|lowercase}}
    </li>
  </ul>
</div>

自定义管道

自定义一个简单的放大倍数的管道指令。
文件名以‘.pipe.ts’结尾,expand-data.pipe.ts

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

@Pipe({name: 'expandData'})
export class ExpandData implements PipeTransform {transform(value: number) {if (value && isNumber(value)) {return 2 * value;} else {return 0;}
  }
}

将管道放在 app 模块的声明数组种,以便模板能够使用,上述代码是标准的格式代表,一切的执行在这个 transform 方法种,并且返回最终结果。我声明了一组数组:[1,2,3,4,5], 通过 ngFor 渲染在 li 列表中。

管道与变更检测

改造下 demo 和管道:

import {Pipe, PipeTransform} from '@angular/core';
import {isNumber} from 'util';
@Pipe({name: 'expandData'})
export class ExpandData implements PipeTransform {transform(data: Array<any> | any) {if (data && isNumber(data)) {return 2 * data;} else if (typeof (data) !== 'string' && data.length > 0) {data = data.filter(o => o.value > 3);
      data.map(o => 2 * o);
      return data;
    }
  }
}
 counts = [{ id: '0', value: 1},
    {id: '1', value: 2},
    {id: '2', value: 3},
    {id: '3', value: 4},
    {id: '4', value: 5}
  ];
  randomChange() {this.counts[Math.round(4 * Math.random())].value = Math.round(10 * Math.random());
  }
<div>
  {{counts|json}}
  <ul>
    <li *ngFor="let count of counts | expandData">
      {{count.value}}
    </li>
  </ul>
  <button nz-button (click)="randomChange()"> 随机改变其中一个数据 </button>
</div>


尽管真实的数据中符合大于 3 的已经超过 2 个,但是页面中还是渲染 2 个数据。

这里只是用了另一种变更检测算法 —— 它会忽略对列表及其子项所做的任何更改。为了通知 Angular 更新,需要重新替换数据,解构是个高效的方案。

非纯管道

Angular 会在每个组件的变更检测周期中执行非纯管道。非纯管道可能会被调用很多次,和每个按键或每次鼠标移动一样频繁。
要在脑子里绷着这根弦,必须小心翼翼的实现非纯管道。一个昂贵、迟钝的管道将摧毁用户体验。

纯管道

Angular 只有在它检测到输入值发生了纯变更时才会执行纯管道。纯变更是指对原始类型值 (String、Number、Boolean、Symbol) 的更改,或者对对象引用 (Date、Array、Function、Object) 的更改。

import {Pipe, PipeTransform} from '@angular/core';
import {isNumber} from 'util';
@Pipe({name: 'expandData',pure:false})
export class ExpandData implements PipeTransform {transform(data: Array<any> | any) {if (data && isNumber(data)) {return 2 * data;} else if (typeof (data) !== 'string' && data.length > 0) {data = data.filter(o => o.value > 3);
      data.map(o => 2 * o);
      return data;
    }
  }
}

正文完
 0