Chào các bạn, hôm nay anh sẽ hướng dẫn mọi người cách truyền dữ liệu từ component cha xuống con là như thế nào?
Trong Angular để truyền dữ liệu từ component cha xuống các component con thì ta sử dụng annotation @Input.
Trong dự án Angular component cha sẽ giao tiếp với component con thông qua thuộc tính properties. Annotation @Input được sử dụng để nhận các giá trị từ properties từ cha xuống con.
Trong ví dụ hôm nay chúng ta sẽ truyền giá trị từ component cha xuống con. Giá trị ta truyền xuống là biến đếm (count) sẽ được truyền từ component cha xuống component con để hiển thị.
1
2
3
4
5
6
7
8
9
10
import { Component, Input } from '@angular/core';
@Component({
selector: 'child-component',
template: '<h2>Child Component</h2>
current count is 8'
})
export class ChildComponent {
@Input() count: number;
}
Đầu tiên chúng ta import annotation @Input từ thư viện angular core.
1
import { Component, Input } from '@angular/core';
Chúng ta định nghĩa template html cho component. Chúng ta viết template html inline nên không cần phải tạo file html cho ví dụ này.
1
2
3
selector: 'child-component',
template: '<h2>Child Component</h2>
current count is 8'
Biến count sẽ được truyền từ component cha xuống để component con có thể hiển thị. Để nhận được giá trị của biến count từ cha. Thì component con sẽ khai báo annotation @Input count với mục đích là sẽ nhận biến count từ cha truyền xuống.
1
2
3
export class ChildComponent {
@Input() count: number;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import { Component} from '@angular/core';
@Component({
selector: 'app-root',
template: '
<h1>Welcome to !</h1>
<button (click)="increment()">Increment</button>
<button (click)="decrement()">decrement</button>
<child-component [count]=Counter></child-component>' ,
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = 'Component Interaction';
Counter = 5;
increment() {
this.Counter++;
}
decrement() {
this.Counter--;
}
}
Trong component cha ta có 2 buttons dùng để tăng và giảm giá trị của biến count.
1
2
<button (click)="increment()">Increment</button>
<button (click)="decrement()">decrement</button>
Dòng tiếp theo ta nhúng component con vào component cha thông qua thẻ child-component. Đồng thời truyền giá trị count qua cho component con thông qua thuộc tính [count] = Counter
1
<child-component [count]=Counter></child-component>
Ngoài cách nhận dữ liệu bằng cách sử dụng annotation @input ở trên.
1
2
3
export class ChildComponent {
@Input() count: number;
}
Ta có thể khai báo input trong thẻ component meta data vẫn có kết quả như nhau. Ví dụ đoạn code sau:
1
2
3
4
5
6
7
@Component({
selector: 'child-component',
inputs: ['count'],
template: '<h2>Child Component</h2>
current count is 8'
})
export class ChildComponent {}
Chúng ta có thể đặt tên biến count là MyCount như sau trong component class của lớp con.
1
2
3
export class ChildComponent {
@Input('MyCount') count: number;
}
Sau đó ở lớp cha ta truyền xuống bằng tên của Input như sau:
1
2
<h1>Welcome to !</h1>
<child-component [MyCount]=ClickCounter></child-component>
Ngoài việc truyền data từ component cha xuống cho con. Thì lớp còn cần phải biết thêm khi nào giá trị của lớp cha thay đổi để nó có thể cập nhật lại. Có 2 cách để có thể phát hiện ra khi input thay đổi là:
ngOnChanges được dùng để Angular phát hiện ra khi nào giá trị thay đổi. Chúng ta sẽ cập nhật thêm component con phương thức ngOnChanges() để khi component cha thay đổi giá trị thì component con sẽ cập nhật giá trị.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import { Component, Input, OnChanges, SimpleChanges, SimpleChange } from '@angular/core';
@Component({
selector: 'child-component',
template: '<h2>Child Component</h2>
current count is 8'
})
export class ChildComponent implements OnChanges {
@Input() count: number;
ngOnChanges(changes: SimpleChanges) {
for (let property in changes) {
if (property === 'count') {
console.log('Previous:', changes[property].previousValue);
console.log('Current:', changes[property].currentValue);
console.log('firstChange:', changes[property].firstChange);
}
}
}
}
Đầu tiên chúng ta import các thư viện cần vào.
1
2
import { Component, Input, OnChanges, SimpleChanges, SimpleChange } from '@angular/core';
Tiếp đến chúng ta thay thêm class OnChanges vào.
1
2
export class ChildComponent implements OnChanges {
Chúng ta viết thêm method ngOnChanges.
1
2
3
4
5
6
7
8
9
10
11
ngOnChanges(changes: SimpleChanges) {
for (let property in changes) {
if (property === 'count') {
console.log('Previous:', changes[property].previousValue);
console.log('Current:', changes[property].currentValue);
console.log('firstChange:', changes[property].firstChange);
}
}
}
Method ngOnchanges sẽ nhận được các sự thay đổi trên properties của component cha và chuyển đổi nó thành object SimpleChanges. Đối tượng SimpleChanges chứa đựng key là tên của thuộc tính và giá trị là đối tượng SimpleChanges. Có được đối tượng SimpleChanges ta có thể lấy được giá trị hiện tại, giá trị trước khi thay đổi. Từ đó ta sẽ cập nhật lại giao diện dựa trên các giá trị ta có.
Chúng ta có thể sử dụng getter và setter để phát hiện ra sự thay đổi.
Trong component con ta tạo một biến tên count.
1
private count = 0;
Chúng ta tạo getter và setter cho biến count và thêm annotation @Input trên phương thức như sau:
1
2
3
4
5
6
@Input()
set count(count: number) {
this.count = count;
console.log(count);
}
get count(): number { return this.count; }