AngularでViewChildを使用して、子コンポーネント、ディレクティブ、またはDOM要素にアクセスする方法
序章
この記事では、AngularのViewChildデコレータを紹介します。
親コンポーネントクラスからディレクティブ、子コンポーネント、またはDOM要素にアクセスしたい場合があります。 ViewChild
デコレータは、指定されたディレクティブ、コンポーネント、またはテンプレート参照セレクタに一致する最初の要素を返します。
前提条件
このチュートリアルを実行したい場合:
- @ angle /cliのインストールを検討してください。
@angular/cli
を使用して、でViewChild
機能をテストするための新しいプロジェクトを作成します。
このチュートリアルは、@angular/core
v13.0.2および@angular/cli
v13.0.3で検証されました。
ディレクティブでのViewChild
の使用
ViewChild
を使用すると、ディレクティブにアクセスできます。
SharkDirective
があるとします。 このディレクティブは、属性appShark
を持つ要素を検索し、要素内のテキストの前に"Shark"
という単語を追加します。
理想的には、@angular/cli
からgenerate
のディレクティブを使用します。
ng generate directive shark --skip-tests
このコマンドは、shark.directive.ts
ファイルを作成します。 そして、ディレクティブをapp.module.ts
に追加します。
app.module.ts
import { SharkDirective } from './shark.directive'; ... @NgModule({ declarations: [ AppComponent, SharkDirective ], ... })
次に、ElementRef
とRenderer2
を使用してテキストを書き直します。 shark.directive.ts
の内容を次のように置き換えます。
shark.directive.ts
import { Directive, ElementRef, Renderer2 } from '@angular/core'; @Directive( { selector: '[appShark]' } ) export class SharkDirective { creature = 'Dolphin'; constructor(elem: ElementRef, renderer: Renderer2) { let shark = renderer.createText('Shark '); renderer.appendChild(elem.nativeElement, shark); } }
次に、コンポーネントテンプレートのテキストを含むspan
にappShark
属性を追加します。 app.component.html
の内容を次のように置き換えます。
app.component.html
<span appShark>Fin!</span>
ブラウザでアプリケーションを表示すると、要素のコンテンツの前に"Shark"
という単語が表示されます。
OutputShark Fin!
これで、SharkDirective
のcreature
インスタンス変数にアクセスし、その値でextraCreature
インスタンス変数を設定することもできます。 app.component.ts
の内容を次のように置き換えます。
app.component.ts
import { Component, ViewChild, AfterViewInit } from '@angular/core'; import { SharkDirective } from './shark.directive'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent implements AfterViewInit { extraCreature!: string; @ViewChild(SharkDirective) set appShark(directive: SharkDirective) { this.extraCreature = directive.creature; }; ngAfterViewInit() { console.log(this.extraCreature); // Dolphin } }
このコードは、セッターを使用してextraCreature
変数を設定しました。 AfterViewInit
ライフサイクルフックが変数にアクセスするのを待機していることに注意してください。これは、子コンポーネントとディレクティブが使用可能になったときです。
ブラウザでアプリケーションを表示すると、"Shark Fin!"
メッセージが表示されます。 ただし、コンソールログには次のように表示されます。
OutputDolphin
親コンポーネントは、ディレクティブから値にアクセスできました。
DOM要素でのViewChild
の使用
ViewChild
を使用すると、テンプレート参照変数を持つネイティブDOM要素にアクセスできます。
テンプレートに#someInput
参照変数を持つ<input>
があるとします。 app.component.html
の内容を次のように置き換えます。
app.component.html
<input #someInput placeholder="Your favorite sea creature">
これで、ViewChild
で<input>
にアクセスし、value
を設定できます。 app.component.ts
の内容を次のように置き換えます。
app.component.ts
import { Component, ViewChild, AfterViewInit, ElementRef } from '@angular/core'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent implements AfterViewInit { @ViewChild('someInput') someInput!: ElementRef; ngAfterViewInit() { this.someInput.nativeElement.value = 'Whale!'; } }
ngAfterViewInit
が起動すると、<input>
の値は次のように設定されます。
OutputWhale!
親コンポーネントは、子DOM要素の値を設定できました。
子コンポーネントでのViewChild
の使用
ViewChild
を使用すると、子コンポーネントにアクセスしてメソッドを呼び出したり、子が使用できるインスタンス変数にアクセスしたりできます。
PupComponent
があるとします。
理想的には、コンポーネントを@angular/cli
からgenerate
に使用します。
ng generate component pup --flat --skip-tests
このコマンドは、pup.component.ts
、pup.component.css
、およびpup.component.html
ファイルを作成します。 そして、コンポーネントをapp.module.ts
に追加します。
app.module.ts
import { PupComponent } from './pup.component'; ... @NgModule({ declarations: [ AppComponent, PupComponent ], ... })
次に、whoAmI
メソッドをPupComponent
に追加すると、次のメッセージが返されます。
pup.component.ts
import { Component, OnInit } from '@angular/core'; @Component({ selector: 'app-pup', templateUrl: './pup.component.html', styleUrs: ['./pup/component.css'] }) export class PupComponent implements OnInit { constructor() { } whoAmI() { return 'I am a pup component!'; } ngOnInit(): void { } }
次に、アプリテンプレートで子コンポーネントを参照します。 app.component.html
の内容を次のように置き換えます。
app.component.html
<app-pup>pup works!</app-pup>
これで、ViewChild
を使用して、親コンポーネントクラス内からwhoAmI
メソッドを呼び出すことができます。 app.component.ts
の内容を次のように置き換えます。
app.component.ts
import { Component, ViewChild, AfterViewInit } from '@angular/core'; import { PupComponent } from './pup.component'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'], }) export class AppComponent implements AfterViewInit { @ViewChild(PupComponent) pup!: PupComponent; ngAfterViewInit() { console.log(this.pup.whoAmI()); // I am a pup component! } }
ブラウザでアプリケーションを表示すると、コンソールログに次のように表示されます。
OutputI am a pup component!
親コンポーネントは、子コンポーネントのwhoAmI
メソッドを呼び出すことができました。
結論
このチュートリアルでは、ViewChild
を使用して、親コンポーネントクラスからディレクティブ、子コンポーネント、およびDOM要素にアクセスしました。
参照が動的に新しい要素に変更されると、ViewChild
はその参照を自動的に更新します。
複数の子にアクセスする場合は、代わりにViewChildrenを使用します。
Angularについて詳しく知りたい場合は、Angularトピックページで演習とプログラミングプロジェクトを確認してください。