$watch
AngularJS では、 の関数を使用してスコープ変数の変更を監視するウォッチャーを指定できました$scope
。Angular で変数の変更 (たとえば、コンポーネント変数) を監視することと同等のものは何ですか?
8 に答える
Angular 2 では、変更検出は自動です...$scope.$watch()
そして$scope.$digest()
RIP
残念ながら、開発ガイドの変更検出セクションはまだ作成されていません (アーキテクチャの概要ページの下部にある「その他のもの」セクションにプレースホルダーがあります)。
変更検出がどのように機能するかについての私の理解は次のとおりです。
- Zone.js は「モンキー パッチを世界に」 -- ブラウザー内のすべての非同期 API をインターセプトします (Angular の実行時)。これが、...
setTimeout()
のようなものではなく、コンポーネント内で使用できる理由です。$timeout
setTimeout()
- Angular は、「変更検出器」のツリーを構築および維持します。コンポーネント/ディレクティブごとに、そのような変更検出器 (クラス) が 1 つあります。( を注入することで、このオブジェクトにアクセスできます
ChangeDetectorRef
。) これらの変更検出器は、Angular がコンポーネントを作成するときに作成されます。ダーティチェックのために、すべてのバインディングの状態を追跡します。これらはある意味で、 Angular 1 がテンプレート バインディング$watches()
用にセットアップする自動化に似ています。Angular 1 とは異なり、変更検出グラフは有向ツリーであり、サイクルを持つことはできません (これにより、以下で説明するように、Angular 2 のパフォーマンスが大幅に向上します)。{{}}
- イベントが発生すると (Angular ゾーン内で)、作成したコード (イベント ハンドラー コールバック) が実行されます。共有アプリケーションのモデル/状態および/またはコンポーネントのビュー状態など、必要なデータを更新できます。
- その後、Zone.js が追加したフックにより、Angular の変更検出アルゴリズムが実行されます。デフォルトでは (つまり、
onPush
どのコンポーネントでも変更検出戦略を使用していない場合)、ツリー内のすべてのコンポーネントが 1 回 (TTL=1) ... 上から深さ優先順に検査されます。(開発モードの場合、変更検出は 2 回 (TTL=2) 実行されます。詳細については、 ApplicationRef.tick()を参照してください。) これらの変更検出オブジェクトを使用して、すべてのバインディングに対してダーティ チェックを実行します。- ライフサイクル フックは、変更検出の一部として呼び出されます。
監視したいコンポーネントデータがプリミティブな入力プロパティ(文字列、ブール値、数値)の場合ngOnChanges()
、変更を通知するように実装できます。
入力プロパティが参照型 (オブジェクト、配列など) であるが、参照が変更されていない場合 (たとえば、既存の配列に項目を追加した場合)、実装する必要がありますngDoCheck()
(詳細については、この SO の回答を参照してください)。これについて)。
コンポーネントのプロパティおよび/または子孫コンポーネントのプロパティのみを変更する必要があります (単一ツリー ウォークの実装、つまり単方向データ フローのため)。これに違反するプランカーがあります。ステートフル パイプもここでつまずく可能性があります。
- ライフサイクル フックは、変更検出の一部として呼び出されます。
- バインディングの変更が見つかった場合は、コンポーネントが更新され、次に DOM が更新されます。変更の検出が終了しました。
- ブラウザーは DOM の変更を認識し、画面を更新します。
詳細については、その他の参考文献をご覧ください。
- Angular の $digest が Angular の新しいバージョンで生まれ変わりました- AngularJS のアイデアが Angular にどのようにマッピングされるかを説明します
- Angular での変更検出について知っておくべきことすべて- 変更検出が内部でどのように機能するかを詳細に説明します
- Change Detection Explained - Thoughtram ブログ 2016 年 2 月 22 日 - おそらく最高のリファレンス
- Savkin's Change Detection Reinventedビデオ - 必ず見てください
- Angular 2 変更検出は実際にどのように機能しますか? - jhade のブログ 2016 年 2 月 24 日
- Zone.js に関するBrian のビデオとMiško のビデオ。Brian's は Zone.js に関するものです。Miško's は、Angular 2 が Zone.js を使用して変更検出を実装する方法についてです。彼はまた、一般的な変更検出についても話しています
onPush
。 - Victor Savkins のブログ投稿: Angular 2での変更検出、Angular 2 アプリケーションの 2 つのフェーズ、Angular、不変性、およびカプセル化。彼は多くの分野をすばやくカバーしますが、時には簡潔になることもあります。
- Ultra Fast Change Detection (Google doc) - 非常に技術的で非常に簡潔ですが、ツリーの一部として構築される ChangeDetection クラスを説明/スケッチします
自動双方向バインディングに加えて、値が変更されたときに関数を呼び出す場合は、双方向バインディングのショートカット構文をより詳細なバージョンに分割できます。
<input [(ngModel)]="yourVar"></input>
の省略形です
<input [ngModel]="yourVar" (ngModelChange)="yourVar=$event"></input>
(例: http://victorsavkin.com/post/119943127151/angular-2-template-syntaxを参照)
次のようなことができます。
<input [(ngModel)]="yourVar" (ngModelChange)="changedExtraHandler($event)"></input>
getter function
orを使用get accessor
して、Angular 2 のウォッチとして機能させることができます。
ここでデモを参照してください。
import {Component} from 'angular2/core';
@Component({
// Declare the tag name in index.html to where the component attaches
selector: 'hello-world',
// Location of the template for this component
template: `
<button (click)="OnPushArray1()">Push 1</button>
<div>
I'm array 1 {{ array1 | json }}
</div>
<button (click)="OnPushArray2()">Push 2</button>
<div>
I'm array 2 {{ array2 | json }}
</div>
I'm concatenated {{ concatenatedArray | json }}
<div>
I'm length of two arrays {{ arrayLength | json }}
</div>`
})
export class HelloWorld {
array1: any[] = [];
array2: any[] = [];
get concatenatedArray(): any[] {
return this.array1.concat(this.array2);
}
get arrayLength(): number {
return this.concatenatedArray.length;
}
OnPushArray1() {
this.array1.push(this.array1.length);
}
OnPushArray2() {
this.array2.push(this.array2.length);
}
}
双方向バインディングにしたい場合は、を使用できますが、変数を変更するたびにイベント[(yourVar)]
を実装yourVarChange
して呼び出す必要があります。
ヒーローの変更を追跡するためのこのようなもの
@Output() heroChange = new EventEmitter();
そして、あなたのヒーローが変わったら、電話してくださいthis.heroChange.emit(this.hero);
バインディングは[(hero)]
あなたのために残りを行います
ここで例を参照してください: