管道介绍
管道可以按指定规则将模板内的数据进行转换。使用管道需要用管道操作符|
来连接模板表达式中左边的输入数据和右边的管道。
@Component({
selector:'pipe-demo',
template:`
My birthday is {{birthday|date}}
`
})
export class PipeDemoComponent{
birthday=new Date(1993,3,15);
}
date
管道是angular的内置管道,存放在CommonModule
里。
管道参数
管道可以使用参数,通过传入的参数来输出不同格式的数据。
My birthday is {{birthday|date:"MM/dd/y"}}
链式管道
一个模板表达式可以连续使用多个管道进行不同的处理,这就是链式管道。
{{expression|pipeName1|pipeName2|...}}
模板表达式expression
的值通过管道pipeName1
处理后再传递给pipeName2
管道处理,直至最后一个管道处理完成后,就可以输出链式管道处理的最终结果。
内置管道
内置管道可以直接在任何模板表达式中被使用,不需要通过import
导入和在模块中声明。
DatePipe
DatePipe
管道用来格式化一个日期数据。
expression|date:format
expression
可以为Date
日期对象、日期字符串或毫秒级的时间戳。format
为自定义的日期格式,angular提供了年月日等标识符,可以根据标识符来自定义日期格式。
@Component({
selector:'pipe-demo-date',
template:`
{{date:date:"y-MM-dd EEEE"}}
`
})
export class PipeDemoDateComponent{
date:Date=new Date('2016-06-08 20:05:08');
}
//输出结果:2018-01-01 Wednesday
JsonPipe
JsonPipe
管道通过JSON.stringify()
来将输入数据对象转成对象字符串,该管道主要用于开发调试。
@Component({
selector:'pipe-demo-json',
template:`
{{jsonObject|json}}
`
})
export class PipeDemoJsonComponent{
jsonObjectt:Object={foo:'bar',baz:'qux',nested:{xyz:3,numbers:[1,2]}};
}
输出结果:{
"foo":"bar",
"baz":"qux",
"nested":{
"numbers":[1,2]
}
}
UpperCasePipe
UpperCasePipe
管道用于将文本中所有小写字母转换成大写字母。
expression|uppercase
LowerCasePipe
LowerCasePipe
管道用于将文本中所有大写字母转换成小写字母。
expression|lowercase
DecimalPipe
DecimalPipe
管道用于对数值的整数与小数部分按照指定规则进行格式化,这种格式化方式也称为本地格式化处理。
expression|number[:digitInfo]
参数digitInfo
格式:
{minIntegerrDigits}.{minFractionDigits}-{maxFractionDIgits}
- minIntegerDigits:整数部分保留最小的位数,默认值为1
- minFractionDigits:小数部分保留最小的位数,默认值为0
- maxFractionDIgits:小数部分保留最大的位数,默认值为3
@Component({
selector:'pipe-demo-number',
template:`
A变量:{{a|number:'3.4-5'}}
B变量:{{b|number:'3.1-5'}}
`,
})
export class PipeDemoNumberComponent{
a:number=2.718281828459045;
b:number=33456;
}
//转换后结果:
a变量:002.71828
b变量:33,456.0
CurrencyPipe
CurrencyPipe
管道可以对数值进行本地货币格式化处理。
expression|currency[:currencyCode[:symbolDisplay[:digitInfo]]]
- 参数
currencyCode
表示要格式化的目标货币格式,其值为ISO 4217货币码,如CNY为人民币、USD为美元、EUR为欧元 - 参数
symbolDisplay
表示以该类型货币的哪种格式显示,其值为布尔值,true
表示显示货币符号如¥、$等,false
则表示显示ISO 4217货币码 -
digitInfo
参数与DecimaPipe
中的digitInfo
参数格式相同
@Component({
selector:'pipe-demo-currency',
template:`
A变量:{{a|currency:'USD':false}}
B变量:{{b|currency:'USD':true:'4.2-2'}}
`
})
export class PipeDemoCurrencyComponent{
a:number=0.259;
b:number=1.3495;
}
//转化结果:
A变量:USD0.259
B变量:$0,001.35
PercentPipe
PercentPipe
管道可以对数值进行本地百分比格式化处理。
expression|percent[:digitInfo]
示例:
@Component({
selector:'pipe-demo-percent',
template:`
A变量:{{a|percent}}
B变量:{{b|percent:'4.3-5'}}
`
})
export class PipeDemoPercentComponent{
a:number=0.259;
b:number=1.3495;
}
//转换结果:
A变量:25.9%
B变量:0,134.950%
SlicePipe
SlicePipe
管道用于裁剪数组或者字符串,并返回裁剪后的目标子集。
expression|slice:start[:end]
SlicePipe
的裁剪功能是基于Array.prototype.slice()
和String.prototype.slice()
方法来实现的。输入值expression
可为数组或者字符串,参数start
和end
为相关的索引。
自定义管道
定义元数据
在使用@Pipe
定义元数据前必须从@angular/core
中引入Pipe
和PipeTransform
。
//sexreform.pipe.ts
import { Pipe,PipeTransform } from '@angular/core';
@Pipe({
name:'sexReform'
})
export class SexReform implements PipeTransform{ //... }
通过@Pipe
装饰器来告诉angular这是一个管道类,@Pipe
的元数据只有一个name
属性,用来指定管道名称,这个名称必须是有效的JS标识符。
实现transform方法
自定义的管道必须继承接口类PipeTransform
,同时自定义管道必须实现PipeTransform
接口的transform()
方法,该方法的第一个参数为需要被转换的值,后面可以有若干个可选转换参数,该方法需要返回一个转换后的值。
//...
export class SexReform implements PipeTransform{
transform(val:string):string{
switch(val){
case 'male': return '男';
case 'female': return '女';
default: return '未知性别';
}
}
}
使用自定义管道
在组件模板中使用自定义管道之前,必须在@NgModule
的元数据declarations
数组中添加自定义管道。
import { SexReform } from 'pipes/sexreform.pipe';
@NgModule({
declarations:[SexReform]
})
//在模板中使用自定义管道
//...
@Component({
selector:'pipe-demo-custom',
template:`
{{sexValue|sexReform}}
`
})
管道的变化监测
angular在每次点击、移动鼠标、定时器触发以及服务器响应等事件后都会对数据绑定进行变化监测,而频繁的变化监测则会引起性能问题。我们可以通过管道让angular使用更简单、更快速的变化监测策略来提高性能。
angular管道有两种变化监测机制,分别对应两种类型的管道,即纯管道和非纯管道。其中纯管道是默认类型。
纯管道
在模板表达式中使用纯管道后,只有在监测到输入值发生纯变更时才会调用纯管道的transform()
方法来实现数据转换,从而将数据更新到页面上。纯变更是指对基本数据类型输入值的变更或对对象引用的更改。
@Component({
selector:'pure-pipe-demo',
template:`
'{{dateObj|date:"y-MM-dd HH:mm:ss EEEE"}}'
'{{dateStr|date:"y-MM-dd HH:mm:ss EEEE"}}'
`
})
export class PurePipeDemoComponent{
dateObj:date=new Date('2017-06-08 20:05:08');
dateStr:string='2017-06-08 20:05:08';
constructor(){
setTimeout(()=>{
this.dateObj.setMonth(11);
this.dateStr='2017-12-08 20:05:08';
},2000);
}
}
//效果:
'2017-06-08 20:05:08 Wednesday'
'2017-12-08 20:05:08 Wednesday'
2s后页面显示:
'2017-06-08 20:05:08 Wednesday'
'2017-12-08 20:05:08 Thursday'
在模板表达式中使用纯管道DatePipe
,只有当输入值发生纯变更后才会调用该管道并更新变化的值。
纯管道的变化监测策略是基于判断基本类型的数据值或对象的引用是否被改变来监测对象变化的。对象引用的监测方式比遍历对象内部所有属性值的监测方式要快得多,angular使用的是对象引用的监测策略,这样能快速地判断是否可以跳过执行管道并更新视图。
非纯管道
使用非纯管道,angular组件在每个变化监测周期都会调用非纯管道,并执行管道的transform()
方法来更新页面数据。可以在管道元数据里将pure
属性值设置为false
来定义非纯管道。
@Pipe({
name:'selectContact',
pure:false
})
给管道添加pure:false
就可以将其定义为非纯管道。非纯管道在每个变化周期内都会去监测并执行selectContact
管道的transform()
方法,对发生变化的数据进行过滤,并将数据同步到模板视图中。
SlicePipe
、AsyncPipe
和JsonPipe
属于非纯管道,非纯异步管道需要接收Promise
或Observable
对象作为输入,并自动订阅这个输入,最终返回该异步操作产生的值。
import { Component,OnInit } from '@angular/core';
import { Observable,Subscriber } from 'rxjs/Rx';
@Component({
selector:'impure-pipe-demo',
template:`
时间:{{time|async}}
`
})
export class ImpurePipeDemoComponent implements OnInit{
time:Observable;
constructor(){}
ngOnInit(){
this.time=new Observable((observer:Subscriber)=>{
setInterval(()=>observer.next(new Date().toLocaleString()),1000);
});
};
}