ng2管道

管道介绍

管道可以按指定规则将模板内的数据进行转换。使用管道需要用管道操作符|来连接模板表达式中左边的输入数据和右边的管道。

@Component({
    selector:'pipe-demo',
    template:`
        <p>My birthday is {{birthday|date}}</p>
    `
})
export class PipeDemoComponent{
    birthday=new Date(1993,3,15);
}

date管道是angular的内置管道,存放在CommonModule里。

管道参数

管道可以使用参数,通过传入的参数来输出不同格式的数据。

<p>My birthday is {{birthday|date:"MM/dd/y"}}</p>

链式管道

一个模板表达式可以连续使用多个管道进行不同的处理,这就是链式管道。

{{expression|pipeName1|pipeName2|...}}

模板表达式expression的值通过管道pipeName1处理后再传递给pipeName2管道处理,直至最后一个管道处理完成后,就可以输出链式管道处理的最终结果。

内置管道

内置管道可以直接在任何模板表达式中被使用,不需要通过import导入和在模块中声明。

常用内置管道的类型及功能

DatePipe

DatePipe管道用来格式化一个日期数据。

expression|date:format

expression可以为Date日期对象、日期字符串或毫秒级的时间戳。format为自定义的日期格式,angular提供了年月日等标识符,可以根据标识符来自定义日期格式。

DatePipe管道日期标志符

@Component({
    selector:'pipe-demo-date',
    template:`
        <p>{{date:date:"y-MM-dd EEEE"}}</p>
    `
})
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:`
        <pre>{{jsonObject|json}}</pre>
    `
})
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:`
        <div>
            <p>A变量:{{a|number:'3.4-5'}}</p>
            <p>B变量:{{b|number:'3.1-5'}}</p>
        </div>
    `,
})
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:`
        <div>
            <p>A变量:{{a|currency:'USD':false}}</p>
            <p>B变量:{{b|currency:'USD':true:'4.2-2'}}</p>
        </div>
    `
})
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:`
        <div>
            <p>A变量:{{a|percent}}</p>
            <p>B变量:{{b|percent:'4.3-5'}}</p>
        </div>
    `
})
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可为数组或者字符串,参数startend为相关的索引。

自定义管道

定义元数据

在使用@Pipe定义元数据前必须从@angular/core中引入PipePipeTransform

//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:`
        <p>{{sexValue|sexReform}}</p>
    `
})

管道的变化监测

angular在每次点击、移动鼠标、定时器触发以及服务器响应等事件后都会对数据绑定进行变化监测,而频繁的变化监测则会引起性能问题。我们可以通过管道让angular使用更简单、更快速的变化监测策略来提高性能。
angular管道有两种变化监测机制,分别对应两种类型的管道,即纯管道和非纯管道。其中纯管道是默认类型。

纯管道

在模板表达式中使用纯管道后,只有在监测到输入值发生纯变更时才会调用纯管道的transform()方法来实现数据转换,从而将数据更新到页面上。纯变更是指对基本数据类型输入值的变更或对对象引用的更改。

@Component({
    selector:'pure-pipe-demo',
    template:`
        <div>
            <p>'{{dateObj|date:"y-MM-dd HH:mm:ss EEEE"}}'</p>
            <p>'{{dateStr|date:"y-MM-dd HH:mm:ss EEEE"}}'</p>
        </div>
    `
})
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()方法,对发生变化的数据进行过滤,并将数据同步到模板视图中。
SlicePipeAsyncPipeJsonPipe属于非纯管道,非纯异步管道需要接收PromiseObservable对象作为输入,并自动订阅这个输入,最终返回该异步操作产生的值。

import { Component,OnInit } from '@angular/core';
import { Observable,Subscriber } from 'rxjs/Rx';
@Component({
    selector:'impure-pipe-demo',
    template:`
        <p>时间:{{time|async}}</p>
    `
})
export class ImpurePipeDemoComponent implements OnInit{
    time:Observable<string>;
    constructor(){}
    ngOnInit(){
        this.time=new Observable<string>((observer:Subscriber<string>)=>{
            setInterval(()=>observer.next(new Date().toLocaleString()),1000);
        });
    };
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 223,924评论 6 521
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 95,776评论 3 402
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 170,954评论 0 366
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 60,576评论 1 300
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 69,589评论 6 399
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 53,105评论 1 314
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 41,480评论 3 427
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 40,457评论 0 278
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,998评论 1 324
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 39,026评论 3 343
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 41,174评论 1 354
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,812评论 5 350
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 42,502评论 3 336
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,979评论 0 25
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 34,101评论 1 275
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 49,674评论 3 380
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 46,204评论 2 363

推荐阅读更多精彩内容