模板之管道
基本概念
管道是一些对数据进行转换和格式化的函数。
使用管道也非常简单,只需要引入管道操作符( | )即可。管道操作符会把左侧的变量或表达式的值传给右侧的管道函数,并返回一个转换后的值。
常见的内置管道
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
共同学习,写下你的评论
评论加载中...
作者其他优质文章