web-dev-qa-db-ja.com

手動による変更検出のトリガ Angular

プロパティMode(): stringを持つAngularコンポーネントを書いています。

どのイベントにも反応せずに、プログラムでこのプロパティを設定できるようにしたいです。

問題は、ブラウザイベントがないと、テンプレートバインディング{{Mode}}が更新されないことです。

この変更検出を手動でトリガーする方法はありますか?

305
jz87

次のいずれかを試してください。

  • ApplicationRef.tick() - AngularJSの$rootScope.$digest()と同様 - つまり、完全なコンポーネントツリーをチェックする
  • NgZone.run(callback) - $rootScope.$apply(callback)と同様 - つまり、Angularゾーン内のコールバック関数を評価します。私は思うが、これがコールバック関数を実行した後に完全なコンポーネントツリーをチェックすることになることは確かではない。
  • ChangeDetectorRef.detectChanges() - $scope.$digest()と同様 - つまり、このコンポーネントとその子だけをチェックする

コンポーネントにApplicationRefNgZone、またはChangeDetectorRefを挿入できます。

531
Mark Rajcok

Angular 2のドキュメントは読むのがとても難しいので、私は受け入れられた答えの参照を使い、例を挙げたいと思います。

  1. NgZoneをインポートする:

    import { Component, NgZone } from '@angular/core';
    
  2. クラスコンストラクタに追加してください

    constructor(public zone: NgZone, ...args){}
    
  3. zone.runを使用してコードを実行します。

    this.zone.run(() => this.donations = donations)
    
102
juanpastas

markForCheck()で更新できました

ChangeDetectorRefをインポート

import { ChangeDetectorRef } from '@angular/core';

それを注入してインスタンス化する

constructor(private ref: ChangeDetectorRef) { 
}

最後に行われるマーク変更検出

this.ref.markForCheck();

これはmarkForCheck()が機能し、detectChanges()が機能しない例です。

https://plnkr.co/edit/RfJwHqEVJcMU9ku9XNE7?p=preview

編集:この例はもう問題を描写していない:(私はそれが修正された新しいAngularバージョンを実行しているかもしれないと思います。

(もう一度実行するにはSTOP/RUNを押します)

57
Nuno Tomas

Angular 2+で、@入力デコレータを試してください

それは親と子のコンポーネント間のいくつかのNiceプロパティバインディングを可能にします。

最初に、親にグローバル変数を作成して、子に渡されるオブジェクト/プロパティを保持します。

次に、親から渡されたオブジェクト/プロパティを保持するために、子にグローバル変数を作成します。

次に、子テンプレートが使用されている親HTMLに、子変数の名前で角括弧表記を追加してから、親変数の名前と同じ値に設定します。例:

<child-component-template [childVariable] = parentVariable>
</child-component-template>

最後に、子プロパティが子コンポーネントで定義されている場合は、入力デコレータを追加します。

@Input()
public childVariable: any

あなたの親変数が更新されるとき、それはその更新を子コンポーネントに渡すべきです、それはそのhtmlを更新するでしょう。

また、子コンポーネントで関数を起動するには、ngOnChangesを見てください。

6
Jeremy Swagger

ChangeDetectorRef.detectChanges()-$ scope。$ digest()に似ています-つまり、このコンポーネントとその子のみをチェックします

0
Chetann