Khởi tạo VPS trong 60 giây · Hoàn tiền trong 7 ngày · Hỗ trợ kỹ thuật 24/7
Bitech Bitech
Hướng dẫn

Hướng dẫn sử dụng ViewChild trong Angular: Truy cập Component, Directive và DOM Element

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 @ViewChild chỉ có sẵn từ vòng đời ngAfterViewInit(). 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ư *ngIf hay *ngFor. Phần tử sẽ có sẵn ngay tại ngOnInit().
    • { static: false } (mặc định): Phần tử được truy vấn sau khi view đã render xong, có sẵn tại ngAfterViewInit().
@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