Life Cycle Hooks in Angular
Life Cycle Hooks là các phương thức đặc biệt mà Angular tự động gọi trong suốt vòng đời của một component hoặc directive. Các hook này giúp chúng ta có thể theo dõi và tương tác với các giai đoạn khác nhau trong quá trình khởi tạo, thay đổi và hủy bỏ của component. Mỗi life cycle hook có một mục đích cụ thể, từ việc khởi tạo giá trị đến việc dọn dẹp tài nguyên khi component bị hủy. Bài viết này sẽ giúp bạn hiểu và sử dụng được các phương thức đặt biệt này!
Component Life Cycle Hooks in Angular
Khi một ứng dụng Angular được chạy, nó tạo và render Root Component. Sau đó nó sẽ tạo và render những component con, cháu tạo thành cây components ( Tree of Components )
Life Cycle Hooks trong Angular là những phương thức được gọi trên các Directive và Component ngay khi có một sự kiện gì đó xảy ra trên nó.
Ví dụ:
- ngOnInit được gọi khi component được khởi tạo.
- Khi Input của component thay đổi, ngOnChanges được gọi
- Trước khi component bị hủy bỏ, ngOnDestroy được gọi
Angular Life Cycle Hooks
Dưới đây là danh sách các life cycle hook trong Angular:
- ngOnChanges
- ngOnInit
- ngDoCheck
- ngAfterContentInit
- ngAfterContentChecked
- ngAfterViewInit
- ngAfterViewChecked
- ngDoDestroy
Change Detection Cycle
Trước khi đi sâu vào tìm hiểu về Life Cycle Hooks, chúng ta hiểu về Change Detection Cycle
Change Detection là một cơ chế giúp cho Angular có thể đồng bộ dữ liệu giữa template với class
Xét ví dụ:
<div>Hello {{name}}</div>
Angular cập nhật DOM mỗi khi giá trị của name
thay đổi.
Vậy làm sao Angular biết được lúc nào giá trị của name
thay đổi? Angular định nghĩa một số sự kiện, ngay khi chúng xảy ra, Angular sẽ tự động chạy Change Detection Cycle. Ví dụ một số sự kiện làm cho Change Detection Cycle chạy: setTimeout(), setInterval, Http requests, ...
Trong quá trình chạy Change Detection Cycle, Angular sẽ kiểm tra giá trị của name
trong class và template, nếu khác nhau, Angular sẽ cập nhật lại giá trị
Constructor
Life Cycle của component được bắt đầu sau khi Angular tạo Component Class. Method đầu tiên nso gọi là Constructor. Tuy nhiên, constructor không phải life cycle hook và cũng không được Angular định nghĩa. Constructor chỉ được gọi khi object của một class được khởi tạo.
Trong Constructor, các Input và Projected Content của component chưa được khởi tạo tại thời điểm này.
ngOnChanges
Phương thức này được gọi mỗi khi input của component thay đổi. Lần chạy đầu tiên, Angular sẽ khởi tạo giá trị cho các input, ngay tại thời điểm này, chúng ta có thể truy cập được giá trị của chúng.
Ví dụ dưới đây dùng để khai báo Input trên Child Component:
@Input() message:string
Tại Parent Component, chúng ta dùng Property Binding để truyền dữ liệu từ ngoài vào
<app-child [message]="message">
</app-child>
Angular sẽ kiểm tra nếu giá trị của message
từ Parent Component thay đổi, nó sẽ gọi method ngOnChange
Lưu ý: Angular sử dụng strict equality operator để phát hiện sự thay đổi. Do đó, đối với object, nếu chúng ta chỉ thay đổi property mà không thay đổi địa chỉ vùng nhớ, Angular sẽ không làm gì trong trường hợp này.
ngOnInit
Phương thức này được gọi sau khi component được khởi tạo và sau phương thước ngOnChange được gọi lần đầu tiên.
Chỉ được gọi một lần.
Tại thời điểm này, chúng ta có thể lấy được giá trị của các Input và thường được sử dụng để khởi tạo logic; ví dụ gọi API
Lưu ý: lúc này vẫn chưa lấy được giá trị của các properties với decorator @ViewChild, @ViewChildren, @ContentChild và @ContentChildren
ngDoCheck
Phương thức này được gọi sau mỗi Change Detection Cycle.
Được gọi sau ngOnChanges và ngOnInit
Lưu ý: cần tránh đưa những đoạn xử lý logic phức tạp tại đây vì nó sẽ ảnh hưởng đến hiệu suất
ngAfterContentInit
Được gọi sau khi Projected Contnent của component được khởi tạo. Tại thời điểm này, chúng ta có thể truy cập vào các properties với decorator @ContentChild và @ContentChildren
Chỉ được gọi một lần kể cả component không có Projected Content
Xét ví dụ sử dụng Projected Content tại Child Component:
<h2>Child Component</h2>
<ng-content></ng-content> <!-- placehodler for content from parent -->
Truyền nội dung từ Parent Component
<h1>Parent Component</h1>
<app-child> This <b>content</b> is injected from parent</app-child>
ngAfterContentChecked
Phương thức này được gọi sau mỗi Change Detection Cycle và sau ngAfterContentInit. Tương tự như ngDoCheck
ngAfterViewInit
Phương thức này được gọi sau khi Component's View và Child Component của chính nó được khởi tạo. Tại thời điểm này, chúng ta có thể sử dụng được các properties với decorator @ViewChild và @ViewChildren
Chỉ được gọi một lần
ngAfterViewChecked
Phương thức này được gọi sau mỗi Change Detection Cycle và sau ngAfterViewInit. Tương tự như ngDoCheck và ngAfterContentChecked
ngOnDestroy
Phương thức này được gọi trước khi Component bị phá hủy. Tại đây bạn có thể Clean Component ví dụ như Unsubscribe Observables để tránh Memory Leaks.
Thứ tự của Life Cycle Hooks
Angular thực thi các hooks theo thứ tự sau:
Trường hợp khởi tạo Component:
- OnChanges
- OnInit
- DoCheck
- AfterContentInit
- AfterContentChecked
- AfterViewInit
- AfterViewChecked
Trường hợp khởi tạo Component và Child Component của chính nó:
- OnChanges
- OnInit
- DoCheck
- AfterContentInit
- AfterContentChecked
- Child Component -> OnChanges
- Child Component -> OnInit
- Child Component -> DoCheck
- Child Component -> AfterContentInit
- Child Component -> AfterContentChecked
- Child Component -> AfterViewInit
- Child Component -> AfterViewChecked
- AfterViewInit
- AfterViewChecked
Trường hợp sau khi Component được khởi tạo:
- OnChanges
- DoCheck
- AfterContentChecked
- AfterViewChecked
Tổng kết
Đến đây bạn đã biết được toàn bộ Life Cycle Hook và cơ chế đồng bộ dữ liệu của Angular.
Hy vọng bài viết này có ích đối với bạn!
All rights reserved