[解決済み】AngularJS 。observe メソッドと $watch メソッドの違い
質問
私は、両方の
Watchers
と
Observers
の中に何かあるとすぐに計算されます。
$scope
は、AngularJSで変更されます。しかし、この2つの違いは一体何なのか、理解できませんでした。
私の最初の理解では
Observers
は、HTML 側の条件である angular 式に対して計算されます。
Watchers
が実行されたとき
$scope.$watch()
関数が実行されます。私の考えは正しいでしょうか?
どのように解決するのですか?
観察()
は
属性
そのため、DOM 属性の値の変化を観察するためにのみ使用することができます。 これは、ディレクティブの内部でのみ使用/呼び出しが可能です。 補間を含む DOM 属性(すなわち、{{}}のもの)を監視/観察する必要がある場合は、$observe を使用してください。
例
attr1="Name: {{name}}"
とすると、ディレクティブの中で
attrs.$observe('attr1', ...)
.
(もし、あなたが
scope.$watch(attrs.attr1, ...)
があるためうまくいきません。
undefined
.) それ以外のものは$watchを使用します。
$watch() はもっと複雑です。 ここで、式は関数でも文字列でもかまいません。 式が文字列の場合、それは パース 'd(つまり、評価されるのは Angular式 を関数に変換します。 (ダイジェストサイクルごとに呼び出されるのはこの関数です。) 文字列式に {{}} を含めることはできません。 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 は ダイジェストサイクル .
スコープを分離したディレクティブはより複雑です。 もし '@' 構文が使われていれば、 $observe または $watch を含むDOM属性(つまり、{{}}のもの)。 ($watch と共に動作するのは、'@' 構文が以下の処理を行うからです。 補間 のない文字列が表示されます)。 どちらを使うか覚えやすいように、この場合にも $observe を使うことをお勧めします。
これらのことをテストするために、私は
プランカー
という2つのディレクティブを定義しています。 ひとつは (
d1
) は新しいスコープを作成せず、もう一方 (
d2
) は分離されたスコープを作成します。 各ディレクティブは同じ6つの属性を持っています。 各属性は、$observe'dと$watch'edの両方があります。
<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が不要な場合もあります。 例えば、属性に数値やブーリアン(文字列ではない)が含まれている場合、一度だけ評価すればよい。
attr1="22"
そして、例えば、リンク関数で。
var count = scope.$eval(attrs.attr1)
. もしそれが単なる定数文字列であれば -
attr1="my string"
- を使用すればよい。
attrs.attr1
をディレクティブに追加します ($eval() は必要ありません)。
以下もご参照ください。 Vojtaのgoogleグループ投稿 については、$watch 式を使用しています。
関連
-
[解決済み】Failed to load resource: net::ERR_FILE_NOT_FOUND loading json.js
-
[解決済み】event.stopPropagationとevent.preventDefaultの違いは何ですか?
-
[解決済み] JavaScriptで "use strict "は何をするのか、その根拠は?
-
[解決済み] let "と "var "の使い分けは?
-
[解決済み] callとapplyの違いは何ですか?
-
[解決済み] Bowerとnpmの違いは何ですか?
-
[解決済み] JavaScriptのnullとundefinedの違いは何ですか?
-
[解決済み] AngularJSで$scope.$watchと$scope.$applyを使用するにはどうすればよいですか?
-
[解決済み] angular-routeとangular-ui-routerの違いは何ですか?
-
[解決済み】AngularJSのディレクティブスコープにおける「@」と「=」の違いは何ですか?
最新
-
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 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】Javascript:getElementById対getElementsById(両方が別のページで動作する)。
-
[解決済み】NodeJS "ESモジュールをロードするためにインポートを使用する必要があります。"
-
[解決済み] React with ES7: Uncaught TypeError: Cannot read property 'state' of undefined [duplicate] (未定義のプロパティ'state'を読み込むことはできません。
-
[解決済み】ある要素を別の要素に移動させるには?
-
[解決済み】JS ファイルが net::ERR_ABORTED 404 (Not Found) を取得する)
-
[解決済み】このオブジェクトの "forEach "はなぜ関数でないのですか?
-
[解決済み】Uncaught ReferenceError。Firebase は定義されていません。
-
[解決済み] カスタムディレクティブの中で評価された属性を取得する方法
-
[解決済み] AngularJSの$evalAsyncと$timeoutの違いは何ですか?
-
[解決済み] angularjs: background-image:url(...) に相当するng-src。