Angular2/4のngOnChangesはオブジェクトプロパティが変わったことを検知しない〜Lifecycle HooksのngOnChages, ngDoCheckの違い〜
ngOnChangesを使って、子に渡したプロパティが変わったことを検知する
/** app.component.ts */ export class AppComponent { public datas = 1; onClick() { this.datas ++; } }
<!-- app.component.html --> <button (click)="onClick()">押してください</button> <app-child [parentProperty]='datas'></app-child>
<!-- child/child.component.ts --> export class ChildComponent implements OnInit, OnChanges { @Input() parentProperty; constructor() { } ngOnInit() { } ngOnChanges() { console.log('changes'); } }
結果
clickするたび、changesが表示される。
ngOnChangesを使って、子に渡したオブジェクトのプロパティが変わったことを検知する
今度は子Componentにオブジェクトをわたして、
そのオブジェクトのプロパティを変更してみる。
<!-- app.component.ts --> export class AppComponent { public datas = { data1: 1, data2: 2 }; onClick() { this.datas.data1 ++; } }
結果
changesが表示されない。
オブジェクトプロパティの変更は検知されない!
stackoverflowで検索
Q. How can I detect if there is a change to any property on settings?
どうやったらオブジェクトプロパティの変更を検知できますか?
A. Angular will only notice if the object has been changed to a different object (i.e., the object reference changed), so ngOnChanges() can't be used to solve your problem. You could implement the ngDoCheck() method in your MyDirective class.
Angularはオブジェクト自体が変更された時(参照先が変わった時)に検知します。 なのでngOnChangesではダメです。 ngDoCheckを実装してください。
ngDoCheckを実装してみる
<!-- child/child.component.ts --> export class ChildComponent implements OnInit, OnChanges { @Input() parentProperty; constructor() { } ngOnInit() { } ngOnChanges() { console.log('changes'); } ngDoCheck() { console.log('do check'); } }
do checkが表示された。
オブジェクトプロパティの変更が検知されている。