外观
Angular 管道
管道概念
管道是一种用于在模板中转换数据的简单函数。它们接受输入值并返回转换后的值,常用于格式化显示数据而不改变原始数据。
示意图:
数据流经管道:
原始数据 → 管道处理 → 格式化显示
模板语法:
{{ value | pipeName }}
带参数:
{{ value | pipeName:arg1:arg2 }}内置管道
常用内置管道
Angular 提供了一系列内置管道用于常见的数据格式化任务。
示意图:
内置管道分类:
┌─────────────────┐
│ 文本转换 │
│ uppercase │
│ lowercase │
│ titlecase │
├─────────────────┤
│ 数字格式化 │
│ number │
│ percent │
│ currency │
├─────────────────┤
│ 日期处理 │
│ date │
├─────────────────┤
│ 数据结构 │
│ json │
│ slice │
│ keyvalue │
└─────────────────┘文本转换管道
改变文本的显示格式。
示意图:
文本转换示例:
输入: 'hello world'
↓ uppercase管道
输出: 'HELLO WORLD'
输入: 'HELLO WORLD'
↓ lowercase管道
输出: 'hello world'
输入: 'hello world'
↓ titlecase管道
输出: 'Hello World'数字格式化管道
格式化数字、货币和百分比。
示意图:
数字格式化:
输入: 1234.567
↓ number:'1.2-2'
输出: 1,234.57
输入: 0.75
↓ percent
输出: 75%
输入: 19.99
↓ currency:'USD'
输出: $19.99日期管道
格式化日期和时间显示。
示意图:
日期格式化:
输入: new Date('2024-12-25')
↓ date:'yyyy-MM-dd'
输出: 2024-12-25
输入: new Date()
↓ date:'short'
输出: 12/25/24, 10:30 AM
输入: new Date()
↓ date:'fullDate'
输出: Wednesday, December 25, 2024管道参数
参数传递
管道可以接受参数来定制转换行为。
示意图:
参数语法:
{{ value | pipe:param1:param2 }}
示例:
日期格式化: {{ today | date:'yyyy-MM-dd' }}
数字精度: {{ pi | number:'1.2-2' }}
货币代码: {{ price | currency:'EUR' }}链式管道
多个管道可以串联使用,数据从左到右依次通过。
示意图:
管道链:
数据 → 管道A → 管道B → 管道C → 最终结果
示例:
{{ message | uppercase | slice:0:10 }}
步骤:
1. 'hello angular' → uppercase → 'HELLO ANGULAR'
2. 'HELLO ANGULAR' → slice:0:10 → 'HELLO ANGU'自定义管道
创建自定义管道
通过 Angular CLI 或手动创建自定义管道来满足特定需求。
示意图:
创建步骤:
1. 定义管道类
2. 实现 PipeTransform 接口
3. 添加 @Pipe 装饰器
4. 注册到模块示例代码:
typescript
@Pipe({
name: 'reverse'
})
export class ReversePipe implements PipeTransform {
transform(value: string): string {
return value.split('').reverse().join('');
}
}使用:
html
<p>{{ 'hello' | reverse }}</p>
<!-- 显示: olleh -->带参数的自定义管道
管道可以接受参数来控制转换逻辑。
示意图:
参数化管道:
数据 + 参数 → 转换逻辑 → 结果
示例:
{{ text | truncate:20 }}实现:
typescript
@Pipe({
name: 'truncate'
})
export class TruncatePipe implements PipeTransform {
transform(value: string, limit: number = 50): string {
if (value.length <= limit) return value;
return value.substring(0, limit) + '...';
}
}纯管道与非纯管道
纯管道
默认管道类型,仅在输入值发生改变时执行。
示意图:
纯管道特性:
输入引用改变 → 重新执行管道
输入引用不变 → 使用缓存结果
适用场景:纯函数式转换非纯管道
每次变更检测都会执行,适用于处理可变对象。
示意图:
非纯管道特性:
每次变更检测 → 重新执行管道
配置方式:
@Pipe({
name: 'impurePipe',
pure: false
})使用场景对比:
typescript
// 纯管道 - 数组引用改变时更新
@Pipe({ name: 'pureArray' })
// 非纯管道 - 数组内容改变时更新
@Pipe({ name: 'impureArray', pure: false })异步管道
处理异步数据
AsyncPipe 用于自动订阅和取消订阅 Observable 或 Promise。
示意图:
异步数据流:
Observable/Promise → AsyncPipe → 最新值
模板: {{ data$ | async }}示例:
typescript
// 组件中
data$ = this.http.get('/api/data');
// 模板中
<div>{{ data$ | async | json }}</div>自动订阅管理
AsyncPipe 自动处理订阅生命周期,避免内存泄漏。
示意图:
组件初始化 → AsyncPipe订阅 → 获取数据
组件销毁 → AsyncPipe取消订阅 → 清理资源管道性能
性能考虑
管道的执行频率影响应用性能,需要合理设计。
示意图:
性能影响因素:
├── 管道复杂度
├── 执行频率
├── 输入数据大小
└── 纯/非纯特性优化策略
提高管道性能的最佳实践。
示意图:
优化方法:
使用纯管道 → 减少不必要执行
避免复杂计算 → 简化转换逻辑
数据预处理 → 组件中准备数据
管道组合 → 合理使用管道链管道与变更检测
变更检测机制
管道如何与 Angular 的变更检测系统交互。
示意图:
变更检测流程:
数据变化 → 触发检测 → 管道执行 → 更新视图
纯管道: 输入引用变化时执行
非纯管道: 每次检测周期执行最佳实践
在变更检测环境中合理使用管道。
示意图:
推荐做法:
┌─────────────────┐
│ 使用纯管道 │ ← 性能更好
│ 避免副作用 │ ← 保持纯净
│ 合理使用async │ ← 自动管理订阅
│ 预处理复杂数据 │ ← 减少模板负担
└─────────────────┘实用管道示例
文件大小格式化
将字节数转换为可读的文件大小。
示意图:
字节转换:
输入: 2048
↓ filesize
输出: 2 KB
输入: 1572864
↓ filesize
输出: 1.5 MB实现:
typescript
@Pipe({ name: 'filesize' })
export class FileSizePipe implements PipeTransform {
transform(bytes: number, decimals: number = 2): string {
if (bytes === 0) return '0 Bytes';
const k = 1024;
const sizes = ['Bytes', 'KB', 'MB', 'GB'];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return parseFloat((bytes / Math.pow(k, i)).toFixed(decimals)) + ' ' + sizes[i];
}
}搜索过滤管道
在列表中实现实时搜索过滤。
示意图:
搜索过滤:
项目列表 + 搜索词 → filter管道 → 过滤结果
使用:
<div *ngFor="let item of items | search:searchTerm">