Thứ tư, 03/05/2017 | 00:00 GMT+7

Quản lý đăng ký trong Angular với Async Pipe


Đường ống không đồng bộ tích hợp trong Angular 2+ cung cấp cho ta một công cụ tuyệt vời để dễ dàng quản lý các đăng ký có thể quan sát được. Với nó, ta có thể học cách tránh phải đăng ký thủ công các có thể quan sát trong các lớp thành phần trong hầu hết các trường hợp.

Giả sử ta muốn có một thiết bị có thể quan sát cung cấp cho ta thời gian hiện tại mỗi giây. Nếu không sử dụng đường ống không đồng bộ, ta có thể làm như sau:

import { Component, OnInit, OnDestroy } from '@angular/core';

import { Observable } from 'rxjs/Observable';
import { Subscription } from 'rxjs/Subscription';
import 'rxjs/add/observable/interval';
import 'rxjs/add/operator/map';

@Component({
  selector: 'app-root',
  template: `Time: {{ time | date:'mediumTime' }}`
})
export class AppComponent implements OnInit, OnDestroy {
  time: Date;
  timeSub: Subscription;

  ngOnInit() {
    this.timeSub = Observable
      .interval(1000)
      .map(val => new Date())
      .subscribe(val => this.time = val);
  }

  ngOnDestroy() {
    this.timeSub.unsubscribe();
  }
}

Trong móc OnInit của ta , ta đã tạo một giá trị có thể quan sát phát ra một giá trị mỗi giây và ánh xạ giá trị đó sang một ngày mới. Sau đó, ta đăng ký vào đó có thể quan sát được và đặt biến lớp thời gian của ta thành giá trị được phát ra. Ta cũng đảm bảo hủy đăng ký khỏi phần có thể quan sát khi thành phần bị phá hủy để tự dọn dẹp.

Trong mẫu, ta đã sử dụng đường ống ngày tích hợp để chuyển ngày thành định dạng phút và giây mong muốn của ta .


Tuy nhiên, nó khá nhiều mã soạn sẵn, và nếu ta quên hủy đăng ký, ta sẽ có nguy cơ tạo rò rỉ bộ nhớ. Ta có thể đơn giản hóa rất nhiều và đây là chức năng tương tự được triển khai bằng cách sử dụng đường ống không đồng bộ thay thế:

import { Component } from '@angular/core';

import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/interval';
import 'rxjs/add/operator/map';

@Component({
  selector: 'app-root',
  template: `Time: {{ time$ | async | date:'mediumTime' }}`
})
export class AppComponent {
  time$ = Observable
    .interval(1000)
    .map(val => new Date());
}

Đường ống không đồng bộ đảm nhận việc đăng ký và mở gói dữ liệu cũng như hủy đăng ký khi thành phần bị phá hủy.


Ta cũng có thể sử dụng đường ống không đồng bộ để mở và chuyển dữ liệu vào đầu vào cho một thành phần con:

app.component.html
<app-child [time]="time$ | async"></app-child>

Và đứa trẻ bây giờ phải làm thực sự ngoài việc hiển thị dữ liệu.

Async Pipe with ngFor

Giả sử ta có sẵn cấu trúc dữ liệu phức tạp hơn một chút để có thể quan sát được và ta đặt độ trễ giả tạo là 1 giây trước khi nhận được giá trị của nó (bắt chước yêu cầu mạng):

import { Component } from '@angular/core';

import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/of';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/delay';

@Component({ ... })
export class AppComponent {
  cities$ = Observable
    .of([
      {name: 'Los Angeles', population: '3.9 million', elevation: '233′'},
      {name: 'New York', population: '8,4 million', elevation: '33′'},
      {name: 'Chicago', population: '2.7 million', elevation: '594′'},
    ])
    .delay(1000);
}

Trong khuôn mẫu, ta có thể mở và đăng ký dữ liệu khi nó đến với lệnh ngFor như sau:

<ul>
  <li *ngFor="let city of cities$ | async">
      Name: {{ city.name }},
      Population: {{ city.population }},
      Elevation: {{ city.elevation }}</li>
</ul>

Async Pipe with ngIf

Đây là một ví dụ sử dụng chỉ thị cấu trúc ngIf. Ta có thể quan sát được như sau:

word$ = Observable.of('Abibliophobia');

Và mẫu của ta trông như thế này:

<span *ngIf="(word$ | async)?.length > 9; else shortWord">
  Long word: {{ word$.value }}
</span>

<ng-template #shortWord>
  Short word: {{ word$.value }}
</ng-template>

Và ta sẽ nhận được:

Long word: Abibliophobia

Hãy chú ý cách ta đặt từ $ có thể quan sát được qua không đồng bộ, nhưng bọc nó trong dấu ngoặc đơn để sau đó có thể kiểm tra độ dài của giá trị chưa được bao bọc. Ta cũng sử dụng toán tử Elvis ( ? ) Để tránh lỗi khi giá trị của từ $ chưa có sẵn.


Tags:

Các tin liên quan