Dev Study
← Angular コース

43. viewChild() — テンプレートの要素をクラスから取得する

テンプレート内の要素や子コンポーネントをクラス側のコードから扱うには viewChild() を使います。inputEl = viewChild.required<ElementRef>('inputEl') と書くと、テンプレートの #inputEl が付いた要素をシグナルとして取得でき、inputEl().nativeElement.focus() のように操作できます。

実務での出番は、フォーカスの制御、スクロール位置の操作、canvasへの描画など「バインディングでは表現できないDOM操作」が必要なときです。子コンポーネントのクラスを指定して取得すれば、そのpublicメソッドを親から呼び出すこともできます。取得結果はシグナルなので、effect と組み合わせて要素の出現に反応することもできます。

注意したいのは、DOMを直接触るのは最終手段だということです。クラスの付け外しは [class.xxx]、表示の切り替えは @if で書けるので、まずバインディングで解決できないかを考えましょう。また required を付けた場合、@if の中など存在しないことがある要素を指定すると実行時エラーになるため、その場合は required なしで取得して undefined を確認します。

サンプルコード(フレームワーク環境が必要なため表示のみ)

import { Component, viewChild, ElementRef } from '@angular/core';

@Component({
  selector: 'app-focus-form',
  template:
    '<input #inputEl placeholder="コメントを入力">' +
    '<button (click)="focusInput()">入力欄へ移動</button>',
})
export class FocusFormComponent {
  // テンプレートの #inputEl をシグナルとして取得する
  inputEl = viewChild.required<ElementRef>('inputEl');

  focusInput() {
    // フォーカス制御はバインディングで書けない操作の代表例
    this.inputEl().nativeElement.focus();
  }
}
サンプルコードで身につける(5本) →

学んだ概念を、素朴な例から実務寄りの例まで5つの具体例で確認します。

公式ドキュメントで詳しく ↗