AngularJS: $observeメソッドと$watchメソッドの違い 質問する

AngularJS: $observeメソッドと$watchメソッドの違い 質問する

AngularJS で何かが変更されるとすぐに、とWatchersの両方が計算されることは知っています。しかし、この 2 つの違いが正確に何なのか理解できませんでした。Observers$scope

私の最初の理解は、関数が実行されたときに実行されるObserversHTML 側の条件である Angular 式に対して計算されるということです。私の考えは正しいでしょうか?Watchers$scope.$watch()

ベストアンサー1

$観察()は、属性オブジェクトなので、DOM 属性の値の変更を監視/観察するためにのみ使用できます。ディレクティブ内でのみ使用/呼び出されます。補間 (つまり、{{}}) を含む DOM 属性を監視/観察する必要がある場合は、$observe を使用します。たとえば
attr1="Name: {{name}}"の場合、ディレクティブでは次のようになりますattrs.$observe('attr1', ...)
(試しても、scope.$watch(attrs.attr1, ...){{}} があるために機能せず、 が返されますundefined。) それ以外の場合は、$watch を使用します。

$ウォッチ()より複雑です。それは「式」を観察/監視することができます。式は関数または文字列のいずれかです。式が文字列の場合、$パース'd(すなわち、角度のある表現)を関数に組み込みます(この関数はダイジェストサイクルごとに呼び出されます)。文字列式には{{}}を含めることはできません。$watchは範囲オブジェクトなので、スコープオブジェクトにアクセスできる場所であればどこでも使用/呼び出すことができます。

  • コントローラー -- 任意のコントローラー -- ng-view、ng-controller、またはディレクティブ コントローラー経由で作成されたコントローラー
  • ディレクティブ内のリンク関数。スコープにもアクセスできるため

文字列は Angular 式として評価されるため、モデル/スコープ プロパティを監視/監視する場合に $watch がよく使用されます。たとえば、 の場合attr1="myModel.some_prop"、コントローラーまたはリンク関数では、scope.$watch('myModel.some_prop', ...)またはscope.$watch(attrs.attr1, ...)(またはscope.$watch(attrs['attr1'], ...)) となります。
(試行すると、attrs.$observe('attr1')文字列 が返されますがmyModel.some_prop、これはおそらく必要なものではありません。)

@PrimosKの回答のコメントで議論されているように、すべての$observesと$watchesは、ダイジェストサイクル

分離スコープのディレクティブはより複雑です。 '@' 構​​文を使用すると、補間 (つまり {{}}) を含む DOM 属性を $observeまたは $watchできます。($watch で機能する理由は、 '@' 構​​文が補間したがって、$watch は {{}} のない文字列を参照します。) いつどちらを使用するかを覚えやすくするために、この場合も $observe を使用することをお勧めします。

これらをテストするために、私はプランカー2 つのディレクティブを定義します。1 つ ( d1) は新しいスコープを作成せず、もう 1 つ ( d2) は分離スコープを作成します。各ディレクティブには同じ 6 つの属性があります。各属性は $observe と $watch の両方の対象になります。

<div d1 attr1="{{prop1}}-test" attr2="prop2" attr3="33" attr4="'a_string'"
        attr5="a_string" attr6="{{1+aNumber}}"></div>

コンソール ログを見て、リンク関数の $observe と $watch の違いを確認します。次に、リンクをクリックして、クリック ハンドラーによって行われたプロパティの変更によってトリガーされる $observe と $watch を確認します。

リンク関数が実行されると、{{}} を含む属性はまだ評価されないことに注意してください (そのため、属性を調べようとすると、 が返されますundefined)。補間された値を確認する唯一の方法は、$observe (または、'@' を使用した分離スコープを使用している場合は $watch) を使用することです。したがって、これらの属性の値を取得することは非同期操作です。(これが、$observe 関数と $watch 関数が必要な理由です。)

場合によっては、$observe や $watch が必要ないこともあります。たとえば、属性に数値またはブール値 (文字列ではない) が含まれている場合は、それを 1 回だけ評価し、次にリンクattr1="22"関数などで を評価します。var count = scope.$eval(attrs.attr1)それが単なる定数文字列である場合はattr1="my string"、ディレクティブで を使用するだけですattrs.attr1($eval() は不要です)。

参照Vojta の Google グループ投稿$watch 式について。

おすすめ記事