はじめに
この記事では、AngularのViewChild
デコレーターを紹介します。
親コンポーネントクラスからディレクティブ、子コンポーネント、またはDOM要素にアクセスする場合があります。ViewChild
デコレーターは、指定されたディレクティブ、コンポーネント、テンプレート参照セレクタに一致する最初の要素を返します。
ディレクティブに対してViewChild
を使用する
ViewChild
を使用すると、ディレクティブにアクセスすることができます。
SharkDirective
があるとします。
理想的には、@angular/cli
を使用してディレクティブを生成
します。
- ng generate directive shark
それ以外の場合は、app.module.ts
に手動で追加する必要があります。
app.module.ts
import { SharkDirective } from './shark.directive';
...
@NgModule({
declarations: [
AppComponent,
SharkDirective
],
...
})
このディレクティブは、属性appShark
を持つ要素を検索し、要素内のテキストの先頭にShark
という単語を追加します。
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);
}
}
次に、それを使用してコンポーネントテンプレートでFin
にShark
を追加します。
app.component.html
<span appShark>Fin!</span>
ブラウザでアプリケーションを表示すると、次のように表示されます。
Output
Shark Fin!
これで、SharkDirective
のcreature
インスタンス変数にアクセスして、extraCreature
インスタンス変数にその値を設定できるようになりました。
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!」
というメッセージが表示されます。ただし、コンソールログでは、次のように表示されます。
Output
Dolphin
親コンポーネントは、ディレクティブから値にアクセスできました。
DOM要素に対してViewChild
を使用する
ViewChild
を使用すると、テンプレート参照変数を持つネイティブなDOM要素にアクセスすることができます。
#someInput
参照変数を持つ<input>
がテンプレートにあるとします。
app.component.html
<input #someInput placeholder="Your favorite sea creature">
これで、ViewChild
を使用して<input>
にアクセスし、値
を設定できます。
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>
の値は次のように設定されます。
Output
Whale!
親コンポーネントは、子のDOM要素の値を設定することができました。
子コンポーネントに対してViewChild
を使用する
ViewChild
を使用すると、子コンポ―ネントにアクセスしてメソッドを呼び出したり、子が使用可能なインスタンス変数にアクセスすることができます。
ChildComponent
があるとします。理想的には、@angular/cli
を使用してコンポーネントを生成
します。
- ng generate component child --flat
それ以外の場合は、child.component.css
とchild.component.html
ファイルを作成し、app.module.ts
に手動で追加する必要があります。
app.module.ts
import { ChildComponent } from './child.component';
...
@NgModule({
declarations: [
AppComponent,
ChildComponent
],
...
})
メッセージを返すChildComponent
にwhoAmI
メソッドを追加します。
child.component.ts
whoAmI() {
return 'I am a child component!';
}
次に、アプリテンプレート内のコンポーネントを参照します。
app.component.html
<app-child>child works!</app-child>
これで、次のようにViewChild
を使用して、親コンポーネントクラスからwhoAmI
メソッドを呼び出すことができます。
app.component.ts
import {
Component,
ViewChild,
AfterViewInit
} from '@angular/core';
import { ChildComponent } from './child.component';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
export class AppComponent implements AfterViewInit {
@ViewChild(ChildComponent) child: ChildComponent;
ngAfterViewInit() {
console.log(this.child.whoAmI()); // I am a child component!
}
}
ブラウザでアプリケーションを表示すると、コンソールログに次のように表示されます。
Output
I am a child component!
親コンポーネントは、子コンポーネントのwhoAmI
メソッドを呼び出すことができました。
まとめ
ViewChild
を使用して、親コンポーネントクラスからディレクティブ、子コンポーネント、DOM要素にアクセスする方法を学びました。
参照が新しい要素に動的に変更された場合は、ViewChild
によってその参照は自動的に更新されます。
複数の子にアクセスしたい場合は、代わりにViewChildren
を使用します。
Angular の詳細については、Angular トピックページで演習とプログラミングプロジェクトをご覧ください。