Tìm hiểu về pipe trong Angular 2
Bài đăng này đã không được cập nhật trong 8 năm
Nếu như bạn đã làm quen với AngularJS 1.x , thì khái niệm pipes
Angular 2 có lẽ không có gì quá xa lạ. Nó chính là filters
trong Angular 1, thậm chí đến tên gọi của một số filter
cũng được thay tương ứng bằng pipes
cùng tên trong Angular 2 ( trừ một số thay đổi nhỏ, có 3 filter
đã biến mất trong Angular 2 là : number, orderBy và filter. Đồng thời có 3 pipes
mới xuất hiện là : asynce, decimal và percent ) . Tuy nhiên, nếu bạn còn lạ lẫm với khái niệm này, hãy cùng tìm hiểu về pipes
trong Angular 2.
Pipe và cách sử dụng
Hiểu một cách đơn giản thì pipes
trong AngularJS là cách để ta thực hiện việc chuyển hóa dữ liệu ( transformation ), để dễ dàng hiển thị ra dưới định dạng như ta mong muốn. Chẳng hạn như trong ví dụ sau
import { Component } from '@angular/core';
@Component({
selector: 'hero-birthday',
template: `<p>The hero's birthday is {{ birthday }}</p>`
})
export class HeroBirthdayComponent {
birthday = new Date(1988, 3, 15); // April 15, 1988
}
nếu để hiển thị ngày sinh bằng cách mặc định như thế này, output của ta sẽ có dạng ri Apr 15 1988 00:00:00 GMT-0700 (Pacific Daylight Time)
, tương đối khó đọc. Bằng cách dùng pipe
date
, build-in có sẵn trong Angular 2, ta có thể chuyển string hiển thị ngày tháng về dạng dễ đọc hơn
template: `<p>The hero's birthday is {{ birthday | date }}</p>`
Output của ta lúc này sẽ là April 15, 1988
, dễ nhìn hơn rất nhiều.
Mặc định, trong Angular 2 đã build-in sẵn các pipes
sau, để ta có thể ngay lập tức sử dungj: currency
, date
, uppercase
, json
, limitTo
, lowercase
, async
, decimal
, percent
.
Như trong ví dụ bên trên, là cách cơ bản để sử dụng pipe
. Nếu cần thiết, ta có thể truyền thêm tham số
<p>The hero's birthday is {{ birthday | date:"shortDate" }}</p>
sẽ cho ra output 04/15/1988
, hay nếu ta dùng
<p>The hero's birthday is {{ birthday | date:"fullDate" }}</p>
sẽ cho output Friday, April 15, 1988
.
Ta cũng có thể chain ,gọi cùng lúc nhiều pipe
<p>The hero's birthday is {{ birthday | date | uppercase }}</p>
cho ta output FRIDAY, APRIL 15, 1988
Custom Pipe
Đôi khi, chỉ sử dụng các pipe
có sẵn là không đủ, tùy theo nhu cầu, ta có thể viết các custom pipe, thực hiện việc chuyển hóa như ý mình muốn. Ta có thể cùng tìm hiểu qua một ví dụ.
Một tình huống khá phổ biến, dễ gặp, đó là khi ta muốn duyệt một mảng, hay một object, theo từng cặp key-value
của nó . Đây là một kịch bản khá thông dụng, và thường thì các ngôn ngữ hay framework đều có hỗ trợ sẵn cả. Ví dụ như trong PHP, đơn giản ta chỉ cần
foreach ($arrayItems as $key => $value) {
// Do something
}
thế nhưng, khá ngạc nhiên là ngFor
của Angular 2 lại không hỗ trợ sẵn cho tình huống này ( có vẻ là vì vấn để performance, nên Angular 2 không khuyến khích xử lí theo hướng này ??? ) . Tuy nhiên Ta có trong tay ngFor
cho phép ta duyệt từng phẩn tử của mảng, hay từng thuộc tính của Object. Ta có trong tay pipes
là công cụ cho phép ta chuyển hóa về mặt hiển thị của dữ liệu . AGHHHH ... ngFor
pipes
.... Hãy cùng thử làm một cái pipes
cho phép ta duyệt từng phần tử theo cặp key-value
. Mục đích cuối cùng là để ta có thể viết theo kiểu như
<table class="table table-striped">
<tbody>
<tr class="odd gradeX" *ngFor="let pair of item | keys">
<td> {{ pair.key }} </td>
<td> {{ pair.value }} </td>
</tr>
</tbody>
</table>
đại loại như thế. Trước tiên, ta cần viết custom pipe của mình. hãy tạm đặt tên nó là KeysPipe
. Hãy tạo một file typescript keys.ts
, đặt đâu tùy bạn, nhưng nên tổ chức code sao cho hợp lí một chút.
import { Pipe, PipeTransform } from '@angular/core'
@Pipe({name: 'keys'})
export class KeysPipe implements PipeTransform {
}
Tạm cái khung thế đã. Ở đây, ta đã khai báo keyword dùng để gọi đến pipe của mình , là
@Pipe({name: 'keys'})
export class KeysPipe
này để có thể sử dụng ở chỗ khác . Và tất nhiên, ta viết dựa trên bộ khung mà Angular2 đã dựng sẵn , nên ta cho nó implements PipeTransform
. Mở PipeTransform
ra, ta sẽ thấy , nó chỉ là cái interface, trong đó khai báo method transform(value: any, ...args: any[])
. Cùng implements nó vào trong KeysPipe
của ta
import { Pipe, PipeTransform } from '@angular/core'
@Pipe({name: 'keys'})
export class KeysPipe implements PipeTransform {
transform(value, args:string[]) : any {
let keys = [];
for (let key in value) {
keys.push({key: key, value: value[key]});
}
return keys;
}
}
Đơn giản chỉ vậy thôi. Ở đây, ta không cần nhận tham số đầu vào gì , nên không cần động tới biến args
. Trước tiên ta khai báo một mảng keys
để làm nơi chứa kết quả trả ra . value
là biến đầu vào, là giá trị ta cần phải biến đổi, ở đây ta hiểu là một Object. Ta đi duyệt từng thuộc tính của value
for (let key in value) {
, và push nó vào trong array chứa keys
theo từng cặp giá trị key-value
.
Việc cuối cùng cần làm trước khi ta có thể sử dụng | keys
, ta phải khai báo pipes
này trong projcect của mình. Trong file app.module.ts
, ta thêm vào
import { KeysPipe } from '../pipes/keys';
var declarations: any[] = [
// Other Component
KeysPipe
];
Và lúc này, ta đã có thể sử dụng custom pipe
của mình, tương tự như các pipes
build-in khác của Angular 2.
All rights reserved