ホームページ  >  記事  >  ウェブフロントエンド  >  angular.js で双方向バインディングを実装する方法についての簡単な説明 $watch $digest $apply_AngularJS

angular.js で双方向バインディングを実装する方法についての簡単な説明 $watch $digest $apply_AngularJS

WBOY
WBOYオリジナル
2016-05-16 15:36:401161ブラウズ

Angular.js の機能、双方向バインディング。

ビューの変更をデータに直接反映できる魔法の機能です。データの変更をリアルタイムでビューに通知します。

これは、次の 3 つの重要なスコープメソッドのおかげです:

$watch
$ダイジェスト
$apply

それらの違いを紹介しましょう:

$watch
これはスコープ上のデータをリッスンするリスナーです

メソッドの説明:

$scope.$watch('参数',function(newValue,oldValue){
 //逻辑处理
})

上記でリスナーを作成しました。
「パラメータ」は、$scope オブジェクトの下のオブジェクト (またはオブジェクトの属性) であり、

形式であることに注意してください。

$scope.name プロパティを監視するとします。

$scope.$watch('name',function(newValue,oldValue){
 //逻辑处理
})

上記のコードと同様、「name」には引用符が必要です

パラメータの後にコールバック関数が続きます。コールバック関数パラメータは、監視対象の属性、変更後の新しい値、および前回の変更前の古い値を返します。

$ダイジェスト

彼は、スコープ内のデータが変更されたかどうかをチェックする責任を負い、特定の属性が変更された場合、すぐにこの属性をリスナー ($watch によって登録されたリスナー) に通知し、リスナーをトリガーし、コールバック関数を実行します。 .

$apply

このメソッドは $digest に非常に似ており、$digest はスコープ内のすべてのデータをチェックします
$apply は rootScope 内のすべてのデータをチェックするのと同等で、親から子まですべてのデータをチェックします

$apply() == $rootScope.$digest()

$apply() メソッドには 2 つの形式があります。

最初の関数はパラメータとして関数を受け入れます。
これにより、$digest 関数がトリガーされ、パラメーター内の関数

が 1 回実行されます

2 番目のタイプはパラメータを受け入れません。
これは $digest の親から子へのサイクルをトリガーするだけです

Angular.js では、$digest は直接呼び出されず、代わりに $scope.$apply() が使用されます

モニターを設定していないのに、ビューとデータが双方向にバインドされるのはなぜですか

たとえば、テキスト ボックス ng-model="name"
このとき、実際には、上記のビューとの双方向バインディングに対応する属性名が $scope オブジェクトの下にあります

それを達成するにはどうすればよいですか?

実際、ng-model="name" または ng-bind="name" または {{name}} を定義するとき
この時点で、angular.js は $scope モデルの "name" 属性のリスナーを自動的に設定します:

$scope.$watch('name', function(newValue, oldValue) {
  //监听 name 属性的变化
});

angular.js がリスナーの自動作成に役立つことが判明したため、このプロパティと $scope.name データはリアルタイムで双方向にバインドされます。

もちろん、データが変更されていることがわかりますが、双方向バインディングは無効ですか?

いいえ

$scope モデルがダイジェスト ループを通過するときに、データがまだ返されていないだけです。

たとえば、メソッドを非同期で呼び出すと、callbac によって返されるデータ
たとえば、setTimeout でスケジュールされたトリガー関数を設定し、モデル データを変更します
つまり、$scope モデルのダイジェスト サイクルが失われ、その結果、モデルは新しいデータに従って更新するように UI に通知しませんでした。

このような問題が発生した場合はどうすればよいですか?

双方向バインディングを実現するには、ダイジェストを手動で呼び出してループ内のデータをチェックする必要があります

上で述べたように、通常はダイジェスト メソッドを直接呼び出さず、$apply メソッドを手動で呼び出して間接的に $digest ループをトリガーします。

次のように:

setTimeout(function() {
 $scope.name= '一介布衣';
 $scope.$apply();
}, 2000);

問題はここです。apply メソッドを手動で呼び出す必要があります

これまでのところ、angular.js は一部のディレクティブとサービスに対して $apply() メソッドを自動的に実装しています。

例: ng-click、ng-model、$timeout サービス、$http サービスなど

呼び出し後、angular.js は自動的に $apply() を呼び出し、双方向のデータ バインディングを実現します。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。