Vòng đời của component trong Angular

Giới thiệu nội dung bài viết

Chào các bạn,hôm nay anh sẽ hướng dẫn mọi người về Vòng đời của component trong Angular là như thế nào?

1.Vòng đời của component

Vòng đời của một component hay một directive trong Angular tính từ lúc nó được tạo ra, nó bị thay đổi và bị phá huỷ. Hiểu được vòng đời của component ta có thể viết code can thiệp trong quá trình component hay direct được tạo ra, được cập nhật và phá huỷ.

Khi ứng dụng Angular được start lên thì đầu tiên nó sẽ tạo và render component cha (hay còn gọi là root component) sau đó nó sẽ tạo và render các component con. Khi mỗi component được load lên, component sẽ kiểm tra xem có data binding vào nó không, dữ liệu có thay đổi không và cập nhật lại chúng. Khi component bị phá huỷ thì chúng sẽ bị remove (xoá) khỏi giao diện web.

Angular cung cấp cho chúng ta một số phương thức về vòng đời của một component. Dựa vào đó chúng ta có thể can thiệp vào quá trình tạo ra component, cập nhật giá trị và phá huỷ của component. Sau đây là thứ tự từ trên xuống dưới về các method sẽ được sử dụng trong vòng đời của một component.

  • ngOnChanges
  • ngOnInit
  • ngDoCheck
  • ngAfterContentInit
  • ngAfterContentChecked
  • ngAfterViewInit
  • ngAfterViewChecked
  • ngOnDestroy

2. ngOnChanges

Phương thức ngOnChanges được gọi khi component phát hiện có giá trị được binding vào component bằng phương pháp Input properties. Để nhận biết được giá trị binding thì ngOnChange quản lý đối tượng SimpleChange. Chúng ta sử dụng @Input trong bài truyền giá trị từ cha xuống con là một ví dụ.

Ví dụ sau ta có component cha truyền giá trị message xuống cho component con (child-component) thông qua properties sau đó component con sẽ dùng @Input để nhận giá trị và binding vào component.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import { Component} from '@angular/core';
import { Customer } from './customer';
 
@Component({
  selector: 'app-root',
  template: '
        <h1>!</h1>
        <p> Message : <input type='text' [(ngModel)]='message'> </p>
        <p> Code : <input type='text' [(ngModel)]='code'></p>
        <p> Name : <input type='text' [(ngModel)]='name'></p>
        <p><button (click)="updateCustomer()">Update </button>
        <child-component [message]=message [customer]=customer></child-component>
        ' ,
 
        styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'ngOnChanges';
  message = '';
  customer: Customer = new Customer();
  name= '';
  code= 0;
 
  updateCustomer() {
    this.customer= new Customer();
    this.customer.name = this.name;
    this.customer.code = this.code;
  }
 
}

Chúng ta có component con với nội dung như sau:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
import { Component, Input, OnInit, OnChanges, SimpleChanges, SimpleChange,ChangeDetectionStrategy  } from '@angular/core';
import { Customer } from './customer';
 
@Component({
    selector: 'child-component',
    template: '<h2>Child  Component</h2>
               <p>Message  </p>
               <p>Customer Name  </p>
               <p>Customer Code  <p>
               <ul><li *ngFor="let log of changelog;"> </li></ul> '
})
export class ChildComponent implements OnChanges, OnInit {
    @Input() message: string;
    @Input() customer: Customer;
    changelog: string[] = [];
 
    ngOnInit() {
        console.log('OnInit');
    }
 
    ngOnChanges(changes: SimpleChanges) {
        console.log('OnChanges');
        console.log(JSON.stringify(changes));
 
        // tslint:disable-next-line:forin
        for (const propName in changes) {
             const change = changes[propName];
             const to  = JSON.stringify(change.currentValue);
             const from = JSON.stringify(change.previousValue);
             const changeLog = `${propName}: changed from ${from} to ${to} `;
             this.changelog.push(changeLog);
        }
    }
}

Đầu tiên chúng ta import thư viện từ angular core như sau:

1
import { Component, Input, OnInit, OnChanges, SimpleChanges, SimpleChange } from '@angular/core';

Tiếp đến ta cài đặt các vòng đời của Angular

1
2
3
4
export class ChildComponent implements OnChanges, OnInit {
    @Input() message: string;
    @Input() customer: Customer;
    changelog: string[] = [];

Trong hàm ngOnChanges ta lấy tất cả các sự thay đổi giá trị của component thông qua đối tượng SimpleChange.

1
2
3
ngOnChanges(changes: SimpleChanges) {
        console.log('OnChanges');
        console.log(JSON.stringify(changes));

Xử lý nghiệp vụ trong hàm ngOnChange cho phù hợp với yêu cầu của chúng ta.

3. ngOninit

Phương thức NgOninit được gọi, khi component được tạo lần đầu tiên. Chúng ta được chạy sau khi hàm constructor và hàm ngOnchange được thực hiện.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import { Component,  OnInit } from '@angular/core';
 
@Component({
  selector: 'child-component',
  template: '
      <h2>Child Component</h2>
      ' ,
  styleUrls: ['./app.component.css']
})
export class ChildComponent implements OnInit {
 
  constructor() {
    console.log('ChildComponent:Constructor');
  }
 
  ngOnInit() {
    console.log('ChildComponent:OnInit');
  }
 }

Đầu tiên chúng ta import thư viện OnInit từ angular core.

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

Tiếp đến chúng ta khai báo cài đặt hàm OnInit.

1
export class ChildComponent implements OnInit {

Cuối cùng chúng ta viết code trong phương thức ngOnInit để can thiệp vào lúc component được tạo ra.

1
2
3
ngOnInit() {
  console.log('ChildComponent:OnInit');
}

4. ngOnDoCheck

Phương thức ngOnDoCheck được gọi mỗi khi nó phát hiện ra có sự thay đổi dữ liệu ở component.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
import { Component, Input, OnChanges, OnInit, SimpleChanges, SimpleChange, DoCheck  } from '@angular/core';
import { Customer } from './customer';
 
@Component({
    selector: 'child-component',
    template: `<h2>Child  Component</h2>
               <p>Message  </p>
               <p>Customer Name  </p>
               <p>Customer Code  </p>
               <p>Do Check count  </p>
               <ul><li *ngFor="let log of changelog;"> </li></ul> `
})
export class ChildComponent implements OnChanges, DoCheck, OnInit {
    @Input() message: string;
    @Input() customer: Customer;
    changelog: string[] = [];
    oldCustomer: Customer= new Customer();
    DocheckCount = 0;
 
    ngOnInit() {
        console.log('OnInit');
        this.oldCustomer = Object.assign({}, this.customer);
    }
 
    ngDoCheck() {
        console.log('Docheck');
        this.DocheckCount++;
        if (this.oldCustomer.name !== this.customer.name || this.oldCustomer.code !== this.customer.code ) {
            const to  = JSON.stringify(this.customer);
            const from = JSON.stringify(this.oldCustomer);
            const changeLog = `DoCheck customer: changed from ${from} to ${to} `;
            this.changelog.push(changeLog);
 
            this.oldCustomer = Object.assign({}, this.customer);
        }
    }
 
    ngOnChanges(changes: SimpleChanges) {
        console.log('OnChanges');
        console.log(JSON.stringify(changes));
 
        // tslint:disable-next-line:forin
        for (const propName in changes) {
             const change = changes[propName];
             const to  = JSON.stringify(change.currentValue);
             const from = JSON.stringify(change.previousValue);
             const changeLog = `${propName}: changed from ${from} to ${to} `;
             this.changelog.push(changeLog);
        }
    }

Đầu tiên chúng ta import DoCheck từ thư viện angular core.

1
import { Component, Input, OnChanges, OnInit, SimpleChanges, SimpleChange, DoCheck  } from '@angular/core';

Chúng ta implement DoCheck interface.

1
export class ChildComponent implements OnChanges, DoCheck, OnInit {

Cuối cùng chúng ta viết code trong hàm ngDoCheck để kiểm tra sự thay đổi và thêm các dòng code mình muốn.

1
2
3
4
5
6
7
8
9
10
11
ngDoCheck() {
        console.log('Docheck');
        this.DocheckCount++;
        if (this.oldCustomer.name !== this.customer.name || this.oldCustomer.code !== this.customer.code ) {
            const to  = JSON.stringify(this.customer);
            const from = JSON.stringify(this.oldCustomer);
            const changeLog = `DoCheck customer: changed from ${from} to ${to} `;
            this.changelog.push(changeLog);
 
            this.oldCustomer = Object.assign({}, this.customer);
        }

5. ngAfterContentInit

Phương thức này được gọi sau khi component được khởi tạo thành công.

1
2
3
4
5
6
@Component({selector: 'my-cmp', template: `...`})
class MyComponent implements AfterContentInit {
  ngAfterContentInit() {
    // ...
  }
}

6. ngAfterContentChecked

1
2
3
4
5
6
7
8
Phương thức này được gọi sau khi Component Content được kiểm tra bởi Angular's Change module.

@Component({selector: 'my-cmp', template: `...`})
class MyComponent implements AfterContentChecked {
  ngAfterContentChecked() {
    // ...
  }
}

7. ngAfterViewInit

Nó tượng tự nhưng ngAfterContentInit but nó được gọi khi component và các component con của nó được khởi tạo thành công. Chỉ được gọi 1 lần sau khi ngAfterContentChecked.

1
2
3
4
5
6
@Component({selector: 'my-cmp', template: `...`})
class MyComponent implements AfterViewInit {
  ngAfterViewInit() {
    // ...
  }
}

8. ngAfterViewChecked

Phương thức này được gọi sau khi các view component cha và các view của component con được kiểm tra xong.

1
2
3
4
5
6
@Component({selector: 'my-cmp', template: `...`})
class MyComponent implements AfterViewChecked {
  ngAfterViewChecked() {
    // ...
  }
}

9. ngOnDestroy

Phương thức ngOnDestroy được gọi trước khi component hoặc directive bị phá huỷ bởi Angular.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import { Component, OnDestroy } from '@angular/core';
 
@Component({
  selector: 'child-component',
  template: '
      <h2>Child Component</h2>
      ',
  styleUrls: ['./app.component.css']
})
export class ChildComponent implements OnDestroy {
 
  constructor() {
    console.log('ChildComponent:Constructor');
  }
 
 
 
  ngOnDestroy() {
    console.log('ChildComponent:OnDestroy');
  }
 
}

Đầu tiên chúng ta import OnDestroy tử angular core.

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

Tiếp đến implement OnDestroy Interface

1
export class ChildComponent implements OnDestroy

Cuối cùng là viết code trong hàm ngOnDestroy

1
2
3
ngOnDestroy() {
    console.log('ChildComponent:OnDestroy');
  }

9. Demo Video

10. Source code

Sourcecode


Mọi người hãy Subscribe kênh youtube dưới đây nhé để cập nhật các video mới nhất về kỹ thuật và kỹ năng mềm

Các khoá học lập trình MIỄN PHÍ tại đây


Comments