Khám phá cách truy cập Child Component, Directive và DOM Element trong Angular bằng decorator @ViewChild cùng các lưu ý quan trọng về lifecycle.
Trong phát triển ứng dụng Angular, ViewChild là một decorator quan trọng giúp component cha có thể tương tác trực tiếp với các component con, directive hoặc các phần tử DOM (DOM Elements) bên trong template của nó.
Bài viết này sẽ hướng dẫn bạn chi tiết cách triển khai @ViewChild qua từng trường hợp cụ thể.
1. Truy cập DOM Element bằng ViewChild và ElementRef
Khi cần thao tác trực tiếp với DOM (như focus vào input, cuộn trang, hoặc thay đổi style), bạn có thể dùng Template Reference Variable kết hợp với @ViewChild.
HTML Template (app.component.html):
<input #nameInput type="text" placeholder="Nhập tên của bạn">
<button (click)="focusInput()">Focus vào ô nhập</button>
TypeScript (app.component.ts):
import { Component, ViewChild, ElementRef, AfterViewInit } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html'
})
export class AppComponent implements AfterViewInit {
@ViewChild('nameInput') nameInput!: ElementRef<HTMLInputElement>;
ngAfterViewInit() {
// Lấy phần tử DOM thông qua nativeElement
console.log(this.nameInput.nativeElement.placeholder);
}
focusInput() {
this.nameInput.nativeElement.focus();
}
}
2. Truy cập và gọi hàm trong Child Component
Để truy cập các thuộc tính hoặc phương thức public của một component con, bạn chỉ cần truyền class của component đó vào @ViewChild.
Child Component (child.component.ts):
import { Component } from '@angular/core';
@Component({
selector: 'app-child',
template: '<p>Child Component đang hoạt động!</p>'
})
export class ChildComponent {
greet() {
return 'Xin chào từ ChildComponent!';
}
}
Parent Component (app.component.ts):
import { Component, ViewChild, AfterViewInit } from '@angular/core';
import { ChildComponent } from './child.component';
@Component({
selector: 'app-parent',
template: '<app-child></app-child>'
})
export class ParentComponent implements AfterViewInit {
@ViewChild(ChildComponent) childComp!: ChildComponent;
ngAfterViewInit() {
console.log(this.childComp.greet());
}
}
3. Quản lý Vòng đời (Lifecycle Hooks) và Tùy chọn Static
Khi làm việc với @ViewChild, bạn cần nắm rõ hai lưu ý quan trọng:
- Thời điểm truy cập: Mặc định, biến được gắn
@ViewChildchỉ có sẵn từ vòng đờingAfterViewInit(). Nếu truy cập ởngOnInit(), giá trị sẽ làundefined. - Tùy chọn
{ static: true }: Từ Angular 8, bạn có thể truyền tham sốstatic:{ static: true }: Dùng khi tham chiếu KHÔNG nằm trong các directive điều kiện như*ngIfhay*ngFor. Phần tử sẽ có sẵn ngay tạingOnInit().{ static: false }(mặc định): Phần tử được truy vấn sau khi view đã render xong, có sẵn tạingAfterViewInit().
@ViewChild('nameInput', { static: true }) nameInput!: ElementRef;
ngOnInit() {
// Hoạt động được nếu static là true
console.log(this.nameInput.nativeElement);
}
4. Mở rộng: Sử dụng ViewChildren cho danh sách phần tử
Nếu bạn có nhiều phần tử con cùng loại (ví dụ danh sách xuất ra bởi *ngFor), hãy sử dụng @ViewChildren thay vì @ViewChild. @ViewChildren sẽ trả về một QueryList chứa tất cả các phần tử phù hợp.
import { Component, ViewChildren, QueryList, AfterViewInit } from '@angular/core';
import { ChildComponent } from './child.component';
@Component({
selector: 'app-parent',
template: `
<app-child></app-child>
<app-child></app-child>
`
})
export class ParentComponent implements AfterViewInit {
@ViewChildren(ChildComponent) children!: QueryList<ChildComponent>;
ngAfterViewInit() {
this.children.forEach(child => console.log(child.greet()));
}
}
Tổng kết
ViewChild là công cụ mạnh mẽ trong Angular giúp bạn giao tiếp trực tiếp với DOM và component con. Hạn chế lạm dụng việc can thiệp trực tiếp vào DOM qua ElementRef để tránh các rủi ro về bảo mật (như XSS), và hãy luôn chú ý đến vòng đời ngAfterViewInit khi truy cập dữ liệu.
Ngày phát hành: 04/06/2026
Nguồn: www.digitalocean.com