前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Angular 自定义管道

Angular 自定义管道

作者头像
阿宝哥
发布2019-11-05 16:11:38
1.5K0
发布2019-11-05 16:11:38
举报
文章被收录于专栏:全栈修仙之路全栈修仙之路

本文将使用 UltimateAngular/angular-pro-src 中的示例,来一步步介绍自定义管道的相关知识。在该示例中,我们将定义一个 FileSizePipe 管道,它用于实现对文件大小进行格式化显示。

切回正题,我们先来看一下数据:

代码语言:javascript
复制
[
  { name: 'logo.svg', size: 2120109, type: 'image/svg' },
  { name: 'banner.jpg', size: 18029, type: 'image/jpg' },
  { name: 'background.png', size: 1784562, type: 'image/png' }
];

上面数组中每一项表示一个文件信息,含有以下字段:

  • name —— 文件名称
  • size —— 文件大小(字节)
  • type —— 文件类型

接下来我们需要实现的功能,是在显示文件信息时,把字节(Byte)转换为兆(MB)。要实现此功能,我们可以利用 Angular 的管道。在 Angular 中自定义管道,需要按照以下步骤:

  • 使用 @Pipe 装饰器定义 Pipe 的 Metadata 信息,如 Pipe 的名称 —— name 属性。
  • 实现 PipeTransform 接口中定义的 transform 方法。

现在我们来新建一个 filesize.pipe.ts 文件,然后定义一个 FileSizePipe 类,该实现实现了 PipeTransform 接口,具体如下:

代码语言:javascript
复制
import { Pipe, PipeTransform } from '@angular/core';

@Pipe({
  name: 'filesize'
})
export class FilesizePipe implements PipeTransform {
  transform(value: any, args?: any): any {
    return null;
  }
}

字节与兆的转换规则:

代码语言:javascript
复制
1 MB = 1024 KB = 1024 * 1024 B

因此按照以上的转换规则,我们可以很容易把字节(Byte)转换为 兆(MB),需要注意的是要处理小数位,这里我们只保留两位小数:

代码语言:javascript
复制
import { Pipe, PipeTransform } from '@angular/core';

@Pipe({
  name: 'filesize'
})
export class FileSizePipe implements PipeTransform {
  transform(size: number, extension: string = 'MB') {
    return (size / (1024 * 1024)).toFixed(2) + extension;
  }
}

定义完 FileSizePipe 管道,我们就可以直接在模板上使用它了:

代码语言:javascript
复制
import { Component, OnInit } from '@angular/core';

interface File {
  name: string,
  size: any,
  type: string
}

@Component({
  selector: 'my-app',
  template: `
    <div>
      <div *ngFor="let file of files">
        <p>{{ file.name }}</p>
        <p>{{ file.size | filesize }}</p>
      </div>
    </div>
  `
})
export class AppComponent implements OnInit {
  files: File[];
  ngOnInit() {
    this.files = [
      { name: 'logo.svg', size: 2120109, type: 'image/svg' },
      { name: 'banner.jpg', size: 18029, type: 'image/jpg' },
      { name: 'background.png', size: 1784562, type: 'image/png' }
    ];
  }
}

需要注意的是与 AngularJS 1.x 的 Filter 一样,Angular 管道也支持参数和管道链。其实,要实现上述的功能,除了在页面模板中使用管道之外,我们也可以在页面渲染前,对数据源进行处理。

前面我们已经在 FileSizePipe 类中定义了 transform 方法,用于实现文件大小进行格式处理。那么现在问题来了,我们可以直接利用 FileSizePipe 对象提供的 transform 方法,来对数据源进行处理么?答案是可以的。

下面我们来介绍在组件类中,如何使用管道服务:

  • 配置 Provider:
代码语言:javascript
复制
import { FilesizePipe } from './filesize.pipe';

@Component({
  selector: 'my-app',
  template: `...`,
  providers: [
    FilesizePipe
  ]
})
  • 注入 FileSizePipe 管道服务:
代码语言:javascript
复制
constructor(
  private fileSizePipe: FileSizePipe
 ) {}
  • 数据处理
代码语言:javascript
复制
mapped: File[];

ngOnInit() {
  this.mapped = this.files.map(file => {
    return {
      name: file.name,
      type: file.type,
      size: this.fileSizePipe.transform(file.size, 'MB')
    };
  });
}
  • 数据展示
代码语言:javascript
复制
<div>
   <div *ngFor="let file of mapped">
      <p>{{ file.name }}</p>
      <p>{{ file.size }}</p>
   </div>
</div>

最终完整的示例如下:

代码语言:javascript
复制
import { Component, OnInit } from '@angular/core';
import { FileSizePipe } from './filesize.pipe';

interface File {
  name: string,
  size: any,
  type: string
}

@Component({
  selector: 'my-app',
  template: `
    <h3>模板使用管道</h3>
    <div>
      <div *ngFor="let file of files">
        <p>{{ file.name }}</p>
        <p>{{ file.size | filesize }}</p>
      </div>
    </div>
    <h3>组件类中使用管道</h3>
    <div>
      <div *ngFor="let file of mapped">
        <p>{{ file.name }}</p>
        <p>{{ file.size }}</p>
      </div>
    </div>
  `,
  providers: [
    FileSizePipe
  ]
})
export class AppComponent implements OnInit {
  files: File[];
  mapped: File[];

  constructor(
  private fileSizePipe: FileSizePipe
 ) {}
  ngOnInit() {
    this.files = [
      { name: 'logo.svg', size: 2120109, type: 'image/svg' },
      { name: 'banner.jpg', size: 18029, type: 'image/jpg' },
      { name: 'background.png', size: 1784562, type: 'image/png' }
    ];

    this.mapped = this.files.map(file => {
      return {
        name: file.name,
        type: file.type,
        size: this.fileSizePipe.transform(file.size, 'MB')
      };
  });
  }
}

有兴趣的同学,也可以直接浏览线上的示例 —— angular-filesize-pipe

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018/08/16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档