Angular2 comunication (Component interaction) - Tương giác giữa các components trong Angular2

Biết là bài này có thể sẽ chỉ dành cho những bạn ít nhiều đã làm về angular2 nhưng do hôm nay cũng làm rồi đụng đến nên mình chọn luôn chủ để này để bắt đầu luôn cho nóng

Angular2 cũng giống như nhiều javascript framework hiện nay đều áp dụng xu hướng, định hướng web component cho hướng phát triển của họ.

Web component là gì?

Đúng như cái nghĩa component (thành phần), chúng ta sẽ tạo ra nhiều components và xếp chúng lại với nhau và tạo thành một ứng dụng ứng dụng hoàn chỉnh. Giống xếp hình y chang chỉ tùy chúng ta thích xếp lần mấy miếng thôi.

Do đó cách giao tiếp giữa những components khá quan trọng trong bất kì một framework nào cũng như những ngữ cảnh sử dụng cách giao tiếp ấy.

Các bạn có thể đọc bản hoàn chỉnh của angular2 team cung cấp ở trang chủ Component interaction. Còn muốn dễ hiểu hơn thì đọc bài này của mình.

1. Pass data từ component cha (parent component) đến component con (child component) thông qua @Input

Ờ cách này chúng ta sẽ define binding decorator @Input ở child sau đó truyền giá trị đó từ parent Child component

import { Component, Input } from '@angular/core';
@Component({
  selector: 'app-child',
  template: `
    <p>My boss father name is:  { { fatherName}}</p>
  `
})
export class AppChildComponent {
  @Input() fatherName: string;
}

Parent component

import { Component } from '@angular/core';
@Component({
  selector: 'app-parent',
  template: `
    <h2>My son say:</h2>
    <app-child
      [fatherName]="myName">
    </app-child>
  `
})
export class AppParentComponent {
  myName: string = 'Dinh';
}

Ở ví dụ trên bạn thấy thằng cha sẽ bảo thằng con nói tên cha nó thông qua attribute là fatherName thông qua @Input ở component con.

2.Thao tác input đầu vào với setter (Intercept input property changes with a setter)

Giống như cách thứ nhất chúng ta cũng dùng @Input để đưa giá trị từ component cha tới component con. Nhưng nếu như cách một chúng ta chỉ đưa thẳng giá trị và hiện thị trức tiếp trên component cha thì angular2 cung cấp cho ta hàm setter để xử lý input đầu vào.

Ở ví dụ này trong setter chúng ta kiểm tra nếu component cha truyền giá trị fatherName là Dinh thì component con sẽ cộng thêm họ và sau đó sẽ hiển thị ra. Child component

import { Component, Input } from '@angular/core';
@Component({
  selector: 'app-child',
  template: `
    <p>My boss father name is:  { { fatherName}}</p>
  `
})
export class AppChildComponent {
  private _fatherName = '';
  @Input()
  set fatherName(name:string){
    if(name==='Dinh'){
      name += ' Duong'
    }
    this._fatherName = name;
  }

  get name():string{
    return this._fatherName;
  }
}

Parent component

import { Component } from '@angular/core';
@Component({
  selector: 'app-parent',
  template: `
    <h2>My son say:</h2>
    <app-child
      [fatherName]="myName">
    </app-child>
  `
})
export class AppParentComponent {
  myName: string = 'Dinh';
}

3.Sử dụng ngOnchanges của Component (Intercept input property changes with ngOnChanges)

Đầu tiên chúng ta cùng đi sơ qua lifecycle của angular2.

Rõ ràng ngOnChanges sẽ được gọi sau khi chúng ta khởi tạo (constructor) component và chạy trước hàm init component. Child component

import { Component, Input, OnChanges } from '@angular/core';
@Component({
  selector: 'app-child',
  template: `
    <p>My boss father name is:  { { fatherName}}</p>
  `
})
export class AppChildComponent implements OnChanges {
  private _fatherName = '';
  @Input()
  set fatherName(name:string){
    if(name==='Dinh'){
      name += ' Duong'
    }
    this._fatherName = name;
  }

  get fatherName():string{
    return this._fatherName;
  }

  ngOnChanges(changes){
    if(changes['fatherName']){
      this.fatherName = changes['fatherName'].currentValue;
    }
  }
}

Parent component

@Component({
  selector: 'app-parent',
  template: `
    <h2>My son say:</h2>
    <button (click)="forceSay()" > Please say </button>
    <app-child
      [fatherName]="myName">
    </app-child>
  `
})
export class AppParentComponent {
  _myName: string = 'Dinh';
  myName = '';

  sayCount = 0;

  forceSay(){
    this.myName = `${this.sayCount++} ${this._myName}`;
  }
}

Mỗi khi giá trị đầu vào thảy đổi từ component cha thì component con sẽ nhận được thông hàm ngOnChanges(changes) với biến changes nhận được sẽ kiểu SimpleChange với 2 giá trị currentValue và previousValue.