Angular2で描画後にDOM操作をしたい場合
例えばAngular2で描画した後にDOMに対してフォーカスを当てたい場合などがあります。
ngAfterViewInit と ngAfterViewChecked を使用する
その際行った際に使用するのが ngAfterViewInit と ngAfterViewChecked です。
HOOK | 説明 | 参考 |
---|---|---|
ngAfterViewInit | コンポーネントのビューが生成された直後に呼ばれます。 | ngAfterViewInit |
ngAfterViewChecked | コンポーネントのビューの変更を確認した後に呼ばれます。 | ngAfterViewChecked |
使用方法
import { Component, AfterViewInit, AfterViewChecked } from '@angular/core';
@Component({
selector: 'my-app',
template: `<h1>Hello {{name}}</h1>`
})
export class AppComponent implements AfterViewInit, AfterViewChecked {
name = 'Angular';
ngAfterViewInit(){
console.log("init");
}
ngAfterViewChecked(){
console.log("checked");
}
}
使用上の注意
Expression has changed after it was checked. Previous value: 'Angular'. Current value: 'Angular2'.
下記のようなコードを書くと上記のようなエラーが発生します。
import { Component, AfterViewInit, AfterViewChecked } from '@angular/core';
@Component({
selector: 'my-app',
template: `<h1>Hello {{name}}</h1>`
})
export class AppComponent implements AfterViewInit {
name = 'Angular';
ngAfterViewInit(){
this.name = "Angular2";
}
}
理由は簡単で ngAfterViewInit やngAfterViewChecked を使用して
直接 template の情報が描き変わるようなことはしてはいけないということです。
描画後に変更を行いたい場合は下記のようにsetTimeoutを使用するなどして
回避する必要があります。
import { Component, AfterViewInit } from '@angular/core';
@Component({
selector: 'my-app',
template: `<h1>Hello {{name}}</h1>`
})
export class AppComponent implements AfterViewInit {
name = 'Angular';
ngAfterViewInit(){
setTimeout(() => this.name = "Angular2");
}
}
また、ngAfterViewChecked はコンポーネントがチェックされるたびに呼ばれるので動作がかなり遅くなったり、場合によっては無限に実行され続ける場合がありますので
必要な場合のみ処理を行うようコードを書くべきなのでしょう。
なにか、間違いやお気づきの点がありましたらコメントくだされば幸いです。
参考記事
Angular2のLifecycle Hooksを理解する
How to run a jquery function in Angular 2 after every component finish loading