为了账号安全,请及时绑定邮箱和手机立即绑定

模板之管道

基本概念

管道是一些对数据进行转换和格式化的函数。
使用管道也非常简单,只需要引入管道操作符( | )即可。管道操作符会把左侧的变量或表达式的值传给右侧的管道函数,并返回一个转换后的值。

常见的内置管道

Angular 内置了一些常用的管道:

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

例子:

// html
<p>{{ birthday | date:'short' }}</p> 
<!-- 输出: 9/20/21, 3:22 PM -->

<p>{{ birthday | date:'medium' }}</p>
<!-- 输出: Sep 20, 2021, 3:22:11 PM -->

<p>{{ birthday | date:'long' }}</p>
<!-- 输出: September 20, 2021 at 3:22:11 PM GMT+8 -->

<p>{{ birthday | date:'full' }}</p>
<!-- 输出: Monday, September 20, 2021 at 3:22:11 PM GMT+08:00 -->

<p>{{ birthday | date:'shortDate' }}</p>
<!-- 输出: 9/20/21 -->

<p>{{ birthday | date:'mediumDate' }}</p>
<!-- 输出: Sep 20, 2021 -->

<p>{{ birthday | date:'longDate' }}</p>
<!-- 输出: September 20, 2021 -->

<p>{{ birthday | date:'fullDate' }}</p>
<!-- 输出: Monday, September 20, 2021 -->

<p>{{ birthday | date:'shortTime' }}</p>
<!-- 输出: 3:22 PM -->

<p>{{ birthday | date:'mediumTime' }}</p>
<!-- 输出: 3:22:11 PM -->

<p>{{ birthday | date:'longTime' }}</p>
<!-- 输出: 3:22:11 PM GMT+8 -->

<p>{{ birthday | date:'fullTime' }}</p>
<!-- 输出: 3:22:11 PM GMT+08:00 -->

<p>{{ birthday | date:"yyyy/MM/dd" }}</p>
<!-- 输出: 2021/09/22 -->

<p>{{ birthday | date:"h:mm:ss" }}</p>
<!-- 输出: 3:29:29 -->

// ts
birthday = new Date(); 

upperCase:把文本全部转换成大写。
lowerCase:把文本全部转换成小写。

例子:

// html
<p>{{ text01 | uppercase }}</p>
<!-- 输出: OUTPUT -->

<p>{{ text02 | lowercase }}</p>
<!-- 输出: input -->

// ts
text01 = 'output';
text02 = 'INPUT';

也可以对管道进行串联:

例子:

// html
<p>{{ birthday | date | uppercase }}</p>
<!-- 输出: SEP 22, 2021 -->

// ts
birthday = new Date(); 

自定义管道

创建管道

例子:

// 文件名:safeHtml.pipe.ts

// 引入装饰器 Pipe 和接口 PipeTransform
import { Pipe, PipeTransform } from '@angular/core';

// 定义管道名称
@Pipe({
  name: 'safeHtml'
})

// 实现 PipeTransform 接口中定义的 transform 方法
export class SafeHtmlPipe implements PipeTransform {

  // value:需要转换的值(即使用管道时,等号左侧的值)
  // args:处理 value 时的附带条件
  transform(value: string, args?: number): string {
    if(!value) return value;
    const num = args || 5;
    return value.slice(0, num) + '......';
  }
}

使用自定义管道

和使用组件一样,首先在对应的模块中引入并声明管道。

例子:

// 文件名:app.module.ts

import { NgModule } from '@angular/core';
import { FormsModule } from "@angular/forms";
import { BrowserModule } from '@angular/platform-browser';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';

// 引入 SafeHtmlPipe
import { SafeHtmlPipe } from './components/safeHtml.pipe';

@NgModule({
  declarations: [
    AppComponent,

    // 声明 SafeHtmlPipe
    SafeHtmlPipe
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    FormsModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

然后,就可以在该模块下的所有组件中使用这个管道了。

例子:

// html 
<p>{{ text01 | safeHtml:3 }}</p>
<!-- 输出:我是天...... -->

<p>{{ text02 | safeHtml }}</p>
<!-- 输出:偶尔投影在...... -->

// ts
text01 = '我是天空里的一片云';
text02 = '偶尔投影在你的波心';

非纯管道

默认情况下,当 Angular 检测到变量或表达式的值有变化时,就会调用管道函数。
当这个值是基本类型时(例如 String、Number、Boolean 等 ),管道可以正常执行,但是当这个值是引用类型时(比如 Array、Object 等),只有引用地址发生变化时,管道才可以正常执行。

例子:

// 文件名:welcome.pipe.ts

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

@Pipe({
  name: 'welcome'
})
export class WelcomePipe implements PipeTransform {
  transform(value:string[]): Array<string> {
    if(!value) return [];
    return value.map((name:string)=>{
      return 'hello '+name;
    });
  }
}

使用已经定义好的管道 welcome:

//  html
<p *ngFor="let name of (nameList | welcome)">
  {{name}}
</p>

<button (click)="AddName()">AddName</button>

// ts
nameList = ['Tom', 'Mess', 'Amy'];

AddName(){
  this.nameList.push('Lili');
}

例子中,当我们点击 AddName 按钮时,并没有将’Lili’添加到页面上,原因就是数组的引用没有改变,所以 Angular 认为该数组仍是相同的,所以不会更新模板。那么,我们可以通过更改数组的引用来实现更新。

例子:

//ts
nameList = ['Tom', 'Mess', 'Amy'];

AddName(){
  this.nameList = [...this.nameList,'Lili'];
  // this.nameList.push('Lili');
}

除了这个方法,我们也可以通过非纯管道来实现引用类型值的变更检测。 默认情况下,我们自定义的管道都是纯管道,可以通过把 pure 标志设置为 false,将纯管道设置成非纯管道:

@Pipe({
  name: 'welcome',
  pure: false
})

如此一来,引用类型值的内部变化也会调用管道函数。

例子:

// 文件名:welcome.pipe.ts

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

@Pipe({
  name: 'welcome',
  pure:false
})
export class WelcomePipe implements PipeTransform {
  transform(value:string[]): Array<string> {
    if(!value) return [];
    return value.map((name:string)=>{
      return 'hello '+name;
    });
  }
}

使用非纯管道 welcome:

//  html
<p *ngFor="let name of (nameList | welcome)">
  {{name}}
</p>

<button (click)="AddName()">AddName</button>

// ts
nameList = ['Tom', 'Mess', 'Amy'];

AddName(){
  // this.nameList = [...this.nameList,'Lili'];
  this.nameList.push('Lili');
}

值得注意的是,这种非纯管道虽然方便简单,但是每一次的页面操作(按键或者鼠标移动、点击),Angular 都会执行一次非纯管道,从而导致应用的性能下降,造成卡顿的现象,因此要慎重使用。


end

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
Web前端工程师
手记
粉丝
1.4万
获赞与收藏
860

关注作者,订阅最新文章

阅读免费教程

  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消