angular管道相关知识
原文地址
https://www.jianshu.com/p/22e0f95bcf24
什么是管道
每个应用开始的时候差不多都是一些简单任务:获取数据、转换它们,然后把它们显示给用户。
获取数据可能简单到创建一个局部变量就行,也可能复杂到从WebSocket中获取数据流。一旦取到数据,我们可以把它们原始值的toString结果直接推入视图中。 但这种做法很少能具备良好的用户体验。 比如,几乎每个人都更喜欢简单的日期格式,例如1988-04-15,而不是服务端传过来的原始字符串格式 —— Fri Apr 15 1988 00:00:00 GMT-0700 (Pacific Daylight Time)。显然,有些值最好显示成用户友好的格式。我们很快就会发现,在很多不同的应用中,都在重复做出某些相同的变换。 我们几乎会把它们看做某种CSS样式,事实上,我们也确实更喜欢在HTML模板中应用它们 —— 就像CSS样式一样。通过引入Angular管道,我们可以把这种简单的“显示-值”转换器声明在HTML中。
管道把数据作为输入,然后转换它,给出期望的输出。
管道(Pipe)可以根据开发者的意愿将数据格式化。
下图显示的就是内置DATE管道,输入值birthday通过管道操作符( | )流到管道date中,根据管道参数来对流入的数据参数化。
如何使用管道
//管道使用语法 {{expression | pipe : arg}} //如果是链式串联: {{expression | pipe1 : arg | pipe2 | pipe3 }}
管道参数化
管道可能接受任何数量的可选参数来对它的输出进行微调。 我们可以在管道名后面添加一个冒号( : )再跟一个参数值,来为管道添加参数(比如currency:'EUR')。 如果我们的管道可以接受多个参数,那么就用冒号来分隔这些参数值(比如slice:1:5)。
可以理解对管道进行参数化的意思是:传入某些参数,对转换结果进行限制性的格式化转换。
即:
{{ birthday | date }}若不传参数,则为默认值,即输出:Dec 26, 2017
{{ birthday | date:"MM/dd/yy" }}传入了参数,对转换结果的格式进行了限制,输出:12/26/2017
当然这些参数化的参数是管道中已经定义好的了,而不是可以随便传入的,管道会根据传入的参数匹配管道中定义好的参数,匹配之后再根据定义好的规则进行不同的格式化转换。
链式管道
//我们可以把管道链在一起,以组合出一些潜在的有用功能。 {{myDataDate | date:"fullDate"}}:Tuesday, December 26, 2017 {{myDataDate | date:"fullDate" | uppercase}}:TUESDAY, DECEMBER 26, 2017
常用的内置管道
管道 类型 功能 DatePipe 纯管道 日期格式化 JsonPipe 非纯管道 使用JSON.stringify()将对象转成json字符串 UpperCasePipe 纯管道 将文本中的字母全部转在大写 LowerCasePipe 纯管道 将文本中的字母全部转成小写 TitleCasePipe 将文本转换成标题格式 DecimalPipe 纯管道 数值格式化 CurrencyPipe 纯管道 货币格式化 PercentPipe 纯管道 百分比格式化 SlicePipe 非纯管道 数组或字符串取切割 I18nPluralPipe 根据expression的值匹配mapping中的值,并将匹配之后的值展示出来 I18nSelectPipe 根据expression匹配mapping中的值,并且返回匹配之后的值
angular管道的变化监测
Angular通过变更检测过程来查找绑定值的更改,并在每一次JavaScript事件之后运行:每次按键、鼠标移动、定时器以及服务器的响应。 这可能会让变更检测显得很昂贵,但是Angular会尽可能降低变更检测的成本。
每一次的变更检测如果都引起管道的运行,那么是否就会造成程序任务的繁重,换句话说,如果每一次的鼠标移动,每一次的键盘按下都调用了这个管道实践,就会使得整个程序的繁忙。
更多情况下,我们不知道什么时候数据变化了,尤其是在那些有很多种途径改动数据的程序中 —— 可能在程序中很远的地方。 组件就是一个通常无法知道那些改动的例子。此外,它会导致削足适履 —— 扭曲我们的组件设计来适应管道。 我们要尽可能保持组件类独立于HTML。组件不应该关心管道的存在。
Angular管道有两种变化监测机制,一种是纯管道(默认),另一种即非纯管道。
有两类管道:纯的与非纯的。 默认情况下,管道都是纯的。我们以前见到的每个管道都是纯的。 通过把它的pure标志设置为false,我们可以制作一个非纯管道。
纯变更和非纯变更实例对比
下面的管道过滤只显示”李”姓的联系人,如果用户输入一个”李”姓联系人,然后回车将该联系人添加至contacts数组中。然后我们会觉得联系人列表应该会实时显示新的联系人,然而并没有。
这是因为Angular优化了管道的监测机制,它会忽略对象内值的变化,只会监测指向对象的指针是否发生改变。
这种管道称为纯管道,虽然纯管道优化了性能,但有时无法满足需求,就像下面的例子那样。这时我们就需要另外一种变化监测机制,也就是非纯管道。我们可以通过将pure设置为false,这样每当我们输入一个李姓名字的时候就可以在成功添加显示这个李姓名字。
select-contactPipe.pipe.ts
/* select-contactPipe.pipe.ts 步骤 : 1、导入Pipe,PipeTransform 2、通过注解定义名字,定义是纯管道还是非纯管道,默认是纯管道 3、定义管道并继承PipeTransform 4、实现继承的方法transform */ import { Pipe, PipeTransform } from '@angular/core'; /* * from:http://blog.csdn.net/qq451354/article/details/58588252?locationNum=15&fps=1 * Usage: * value | selectContactPipe:exponent * Example: * contacts = [{name: '张三'}, {name: '李四'}]; * {{ contacts | selectContactPipe: '李' }} * output:李四 */ @Pipe({ name: 'selectContactPipe', //pure: false }) export class SelectContanctPipe implements PipeTransform { transform(allContacts: Array<string>, prefix: string) { return allContacts.filter(contact => contact.name.match(prefix)); } }
test.html
<input type="text" #box (keyup.enter)="addContact(box.value); box.value=''" placeholder="输入联系人后回车添加" /> <div *ngFor="let contact of (contacts | selectContactPipe: '李')"> {{contact.name}} </div>
test.component.ts
contacts = [{name: '张三'}, {name: '李四'}]; addContact(name: string) { this.contacts.push({name}); }
纯管道(Pure Pipe)
使用纯管道时,只有监测到输入值发生纯变更才会调用纯管道的transform方法来转换数据。
纯变更是指对基本数据类型输入值的变更,或对对象的引用放生改变。
非纯管道(Impure Pipe)
使用非纯管道,Angular组件在每个变化监测周期都会调用非纯管道。每个变化周期指的是每次的点击,回车等事件发生就会调动检测机制从而监测数据是否发生变化,并且这样的检测不仅仅可以检测出纯变更,同样能监测出非纯变更,即对象的地址不变,但内容变化了同样可以检测出来。
//设置非纯管道 @Pipe({ name: 'selectContact', pure: false //设置非纯管道 })
代码资源
angular实例代码(https://github.com/crk123kk/angular-example)中的angular-pipe,这其中的代码都是我在写博客的时候根据自己的知识掌握敲出来的实例代码,希望对读者有所帮助。
参考网址
管道的相关知识
http://blog.csdn.net/qq451354/article/details/58588252?locationNum=15&fps=1
https://www.pocketdigi.com/20170209/1563.html
https://segmentfault.com/a/1190000008262691