Angular で @Input() 値が変化したことを検出するにはどうすればよいでしょうか? 質問する

Angular で @Input() 値が変化したことを検出するにはどうすればよいでしょうか? 質問する

親コンポーネント ( CategoryComponent )、子コンポーネント ( videoListComponent )、および ApiService があります。

大部分は正常に動作しています。つまり、各コンポーネントは JSON API にアクセスし、Observable を介して関連データを取得できます。

現在、ビデオ リスト コンポーネントはすべてのビデオを取得するだけですが、これを特定のカテゴリのビデオだけにフィルター処理したいので、 を介して categoryId を子に渡すことでこれを実現しました@Input()

カテゴリコンポーネント.html

<video-list *ngIf="category" [categoryId]="category.id"></video-list>

これは機能し、親 CategoryComponent カテゴリが変更されると、categoryId 値が渡されますが@Input()、その後、VideoListComponent でこれを検出し、APIService 経由でビデオ配列を再度要求する必要があります (新しい categoryId を使用)。

$watchAngularJS では、変数に対して を実行します。これを処理する最善の方法は何ですか?

ベストアンサー1

実際には、Angular2+ の子コンポーネントで入力が変更されたときにそれを検出して対応する方法は 2 つあります。

  1. 以前の回答でも述べたように、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
        
    }
    

ドキュメントリンク:変更時、 シンプルチェンジ、 シンプルチェンジ
デモ例: 見てみましょうこの愚か者

  1. あるいは、次のように入力プロパティ セッターを使用することもできます。
    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: 角度変化検出は、状況によっては依然として機能しない場合があります。

通常、データが JS プリミティブ データ型 (文字列、数値、ブール値) である場合、親コンポーネントが子に渡すデータを変更するたびに、setter と ngOnChanges の両方の変更検出が実行されます。ただし、次のシナリオでは実行されず、動作させるために追加のアクションを実行する必要があります。

  1. 親から子にデータを渡すためにネストされたオブジェクトまたは配列(JSプリミティブデータ型の代わりに)を使用している場合、変更検出(setterまたはngchangesのいずれかを使用)が起動しない可能性があります。これは、ユーザーmuetzerichの回答でも言及されています。解決策については、ここ

  2. Angularコンテキストの外部(つまり外部)でデータを変更する場合、Angularは変更を認識しません。Angularに外部の変更を認識させ、変更検出をトリガーするには、コンポーネントでChangeDetectorRefまたはNgZoneを使用する必要があります。これ

おすすめ記事