Tìm kiếm trang web

javascript - Cách sử dụng ViewChild đúng cách


Ứng dụng Angular này chỉ bao gồm thành phần app-root với một <div> và một <button>.

Khi một nút được nhấp, hàm onClick() sẽ ghi vào console đối tượng div_a với:

console.log("...onClick() div_a:", this.div_a);

với div_a được định nghĩa bằng câu lệnh sau:

@ViewChild('div_a', { static: false }) div_a: Component;

Câu hỏi: tại sao cả hai hàm ngOnInit và constructor đều ghi log rằng div_a là undefined? Làm thế nào để khắc phục vấn đề các hàm này không thể sử dụng đối tượng div_a?

Dưới đây là liên kết đến dự án Stackblitz (xin lưu ý rằng nhánh GitHub được liên kết với dự án stackblitz này cần phải được chuyển từ nhánh master sang nhánh qViewChild).

https://stackblitz.com/edit/angular-r9hwbs?file=src%2Fapp%2Fwidget-a%2Fwidget-a.component.html

Câu trả lời #1

Dựa trên tài liệu, các truy vấn ViewChild và ViewChildren được thực hiện trước AfterViewInit, vì vậy bạn sẽ cần truy cập chúng ở đó. Chỉ truy cập div_a sẽ không hoạt động trừ khi bạn gắn thẻ nó trong template.

Trong số những người khác, những đứa trẻ mà bạn có thể tiếp cận là:

  • Bất kỳ lớp nào với chú thích @Component hoặc @Directive
  • Một biến tham chiếu mẫu dưới dạng chuỗi (ví dụ: query <my-component #cmp></my-component> với @ViewChild('cmp'))

Vì vậy bạn sẽ cần một thứ gì đó như thế này:

<p #myPara>
  Start editing to see some magic happen :)
</p>
import { Component, ViewChild, AfterViewInit } from '@angular/core';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent implements AfterViewInit  {
  @ViewChild('myPara', {static: false}) paragraph;


  ngAfterViewInit() {
    console.log(this.paragraph) // results in -> ElementRef {nativeElement: p}
  }
}

Chớp nhoáng

Câu trả lời #2

Khi sử dụng @ViewChild KHÔNG sử dụng ngOnInit hoặc constructor vì nó chưa được nạp. Hãy sử dụng ngAfterViewInit()