[解決済み] Angularで@Input()の値が変更されたときに検出する方法は?
質問
親コンポーネント( カテゴリコンポーネント )、子コンポーネント( videoListComponent ) とApiServiceがあります。
例えば、各コンポーネントはjson APIにアクセスし、observablesを介して関連データを取得することができます。
現在、動画リスト コンポーネントはすべての動画を取得するだけですが、これを特定のカテゴリに属する動画だけにフィルタリングしたいと考え、カテゴリ ID を
@Input()
.
CategoryComponent.html
<video-list *ngIf="category" [categoryId]="category.id"></video-list>
これは動作し、親 CategoryComponent のカテゴリが変更されると、categoryId 値が
@Input()
しかし、VideoListComponent でこれを検出し、APIService を介して (新しい categoryId で) 動画の配列を再要求する必要があります。
AngularJSの場合、私なら
$watch
を変数に追加します。これを処理する最良の方法は何でしょうか?
どのように解決するのですか?
実は、angular2+の子コンポーネントで入力が変化したことを検知して対処するには、2つの方法があります。
- を使用することができます。 ngOnChanges() ライフサイクルメソッド 古い回答にもあるように
@Input() categoryId: string;
ngOnChanges(changes: SimpleChanges) {
this.doSomething(changes.categoryId.currentValue);
// You can also use categoryId.previousValue and
// categoryId.firstChange for comparing old and new values
}
ドキュメントのリンクです。
ngOnChanges,
SimpleChanges,
シンプルチェンジ
デモの例 見る
このプランカー
- また 入力プロパティセッター を以下のように設定します。
private _categoryId: string;
@Input() set categoryId(value: string) {
this._categoryId = value;
this.doSomething(this._categoryId);
}
get categoryId(): string {
return this._categoryId;
}
ドキュメントのリンクです。見る こちら .
デモの例。見てください このプランカー .
どのようなアプローチをとるべきでしょうか?
コンポーネントに複数の入力がある場合、ngOnChanges() を使用すると、ngOnChanges() 内ですべての入力の変更を一度に取得します。このアプローチを使用すると、変更された入力の現在と以前の値を比較し、それに応じてアクションを実行することもできます。
しかし、特定のひとつの入力だけが変化したときに何かしたい (そして他の入力は気にしない) 場合は、入力プロパティ・セッターを使うほうがシンプルかもしれません。しかし、この方法は、変更された入力の前と現在の値を比較する内蔵の方法を提供しません(ngOnChangesライフサイクルメソッドを使用して簡単に行うことができます)。
2017-07-25を編集しました。angularの変更検出は、いくつかの状況下でまだ発火しないかもしれない
通常、セッターと ngOnChanges の両方に対する変更検出は、親コンポーネントが子コンポーネントに渡すデータを変更するたびに発生します。 ただし、そのデータがJSプリミティブデータタイプ(文字列、数値、ブーリアン)である場合に限ります。 . しかし、次のようなシナリオでは、これは発生しないので、動作させるためには、余分なアクションを行う必要があります。
-
親から子へデータを渡すために(JSプリミティブデータタイプの代わりに)ネストされたオブジェクトや配列を使っている場合、(セッターやngchangesを使った)変更検出が行われないことがあります。解決策については、以下をご覧ください。 こちら .
-
もし、angularのコンテキストの外側(つまり、外部)でデータを変異させている場合、angularはその変更を知ることができません。外部からの変更をangularに認識させ、それによって変更検出をトリガーするために、あなたのコンポーネントでChangeDetectorRefまたはNgZoneを使用する必要があるかもしれません。以下を参照してください。 これ .
関連
-
Angular CLIでモジュール "angular-devkit/build-angular" が見つからない問題を解決する。
-
angularjs ポップアップボックスの方法1
-
[解決済み] Angular/RxJS `Subscription` からいつ退会すればいいのか?
-
[解決済み] ExpressionChangedAfterItHasBeenCheckedErrorの説明
-
[解決済み] Angularアプリを本番用にバンドルする方法
-
[解決済み] 予算内の警告、初期値で最大値を超える
-
[解決済み】Angularでルート変更を検出する方法は?
-
[解決済み] Angular2の括弧、括弧、アスタリスクの違いは何ですか?
-
[解決済み] Angular 6 素材マットセレクトの変更方法が削除されました。
-
[解決済み] NgModule.schemasにCUSTOM_ELEMENTS_SCHEMAを追加してもエラーが表示される。
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
Angularフレームワーク入門
-
[解決済み] ExpressionChangedAfterItHasBeenCheckedErrorの説明
-
[解決済み] Angularで変更検知を手動でトリガーする
-
[解決済み] 例外が発生しました。既知のネイティブプロパティではないため、'ngFor'にバインドできない
-
[解決済み】Angular 2 - innerHTML スタイリング
-
[解決済み] Angularアプリケーションが本番モードと開発モードのどちらで動作しているかを確認する方法
-
[解決済み] angular2 tslintの警告を止めるためにコンポーネントのデフォルトプレフィックスを変更する方法
-
[解決済み] Angular2の変更検出:ネストされたオブジェクトに対してngOnChangesが発生しない
-
[解決済み] テンプレート内の *ngIf else if
-
[解決済み] Angularチュートリアルのpipeメソッドとtapメソッドとは何ですか?