AngularDartで親コンポーネントから渡されるデータの変更を監視する方法
概要
親コンポーネントのデータを子コンポーネントに渡して、その値を子コンポーネントで利用出来ますが、今回そのデータ自体が親コンポーネントで更新された際の動作を監視する方法を調べたのでメモします。
コード
子コンポーネント
子コンポーネントは以下のとおりです。
class ChildComponent implements AfterChanges {
@Input()
List<String> something;
@override
void ngAfterChanges() {
print('なんかsomethingの値が更新されたよ!');
}
}
親コンポーネント
で、親側のparent_component.html
は以下のような内容
<child [something]="somethingByParent"></child>
<button (click)="test()">test</button>
親側のparent_component.dart
は以下。
class ParentComponent implements OnActivate {
List<String> somethingByParent;
@override
void onActivate(_, RouterState current) async {
somethingByParent = ['a', 'b'];
}
void test() {
// List.fromは、型宣言を省略すると戻り値の型がList<dynamic>になってしまうので、
// ちゃんと型付きの変数宣言をしてあげる必要が有る。
final List<String>tmp = List.from(somethingByParent)..add('c');
somethingByParent = tmp;
}
}
これで、test
ボタンをクリックすれば、親コンポーネントのtest()
が実行されて、somethingByParent
の中身を新しい値で上書きします。
そうするとその度に、@Input
でそのsomethingByParent
のデータを参照している子コンポーネント側では、something
にsomethingByParent
の値が入ってきた後に、自動的にngAfterChanges
が実行されます。
なお、AngularDartでは、オブジェクトの内容の更新までは自動で検知(今回のAfterChanges等)はしてくれないようで、変数の中身自体を上書きしてあげる必要が有ります。
以下は、正しく子コンポーネント側でAfterChangesなどの変更検知イベントが動かない例です。
// NG1
// 変数を上書きせずにオブジェクトの内容のみ変更している為NG
somethingByParent.add('c');
// NG2
// Dartの制限なのかよく分かっていないが、以下の例だと実質somethingByParentオブジェクトである事自体には変わりが無いため、
// 結果的に子コンポーネントでAfterChangesは呼ばれない。
final List<String>tmp = somethingByParent;
tmp.add('c');
somethingByParent = tmp;
感想
Angular自体初めてなので、完璧に五里霧中です。 ただ、今回コンポーネント間でデータをやり取りする処理を書いてみて、型が無いとコレは無茶苦茶大変だな、という事は容易に想像できたので、やはりAngularDart自体はナイスな選択肢だなと言う思いが強くなりました。
参考
Lifecycle Hooks PREFER implementing AfterChanges to OnChanges
公開日:2019/04/15