この記事では主に AngularJs の双方向バインディングの原理 (データ バインディングの仕組み) を紹介しますが、編集者はこれが非常に優れていると考えたので、参考として共有します。編集者をフォローして見てみましょう
それでは、双方向バインディングとは何でしょうか? 以下で簡単に説明しましょう。
まず、データバインディングを理解する必要があります。私たちが目にするウェブサイトのページは、データとデザインの 2 つの部分で構成されています。デザインをブラウザが理解できる言語に変換することは、HTML と CSS が主に行うことです。ページ上にデータを表示し、特定のインタラクティブな効果 (クリックやその他のユーザー操作や対応するページの反応など) をもたらすのが js の主な仕事です。多くの場合、データを更新するたびにページを更新 (リクエストの取得) することはできず、代わりにバックエンドから関連データをリクエストし、更新せずにロードすることでページを更新します (リクエストの送信)。データが更新された後、ページ上の対応する場所に対応する変更が自動的に行われます。これがデータ バインディングです。
以前の開発モデルでは、このステップでは通常 jq を使用して DOM 構造を操作し、ページを更新します。ただし、これには多くのコードと多くの操作が必要になります。最初にバックエンドから取得したデータからページ上で実行する必要がある操作を判断できれば、データが変化したときにページ内の関連コンテンツも自動的に変更され、フロントエンドの開発が大幅に容易になります。末端のエンジニア。新しいフレームワーク(angualr、react、vueなど)では、データを監視することで変更があれば、記述されたルールに従ってページを修正することでデータバインディングを実現します。データ バインディングは、VM (モデル ビュー、データとページ間の変換規則) を介して M (モデル、データ) を V (ビュー) に変更したものであることがわかります。
双方向バインディングにより、逆パスが追加されます。ユーザーがページを操作すると (入力に値を入力するなど)、データは時間の経過とともに変更される可能性があり、データの変更に応じて、ページの別の部分に対応する変更が行われます。一般的な例は、淘宝網のショッピング カートです。商品の数量が変化すると、商品の価格も変化する可能性があります。これにより、V-M-VM-V の双方向バインディングが実現します。
AngularJs は、スコープ モデルにリスニング キューを設定して、データの変更をリッスンし、ビューを更新します。何かをビュー (html) にバインドするたびに、AngularJs は $watch キューに $watch を挿入して、監視しているモデルに変更があるかどうかを検出します。 $digest ループは、角度コンテキストで処理できるイベントをブラウザーが受信したときに起動します。 $digest はすべての $watch を反復処理します。したがって、DOM が更新されます。
$watch
これは、現在のスコープ $scope の下で、すべての $watches を管理する責任を負う $watchers のオブザーバー パターンに似ています。それを UI にバインドすると、 $watch が自動的に作成され、$watchers に配置されます。
controller.js
app.controller('MainCtrl', function($scope) { $scope.Hello = "Hello"; $scope.world = "World"; });
index.html
<p>{{Hello}}</p>
ここで、$scope に 2 つの変数 を追加しても、UI にバインドされるのは 1 つだけなので、ここで生成されるのは 1 つだけです。 watch
$digest
ブラウザが角度コンテキストによって処理できるイベントを受信すると、$digest ループがトリガーされます。 $digest は $watch を走査します。$watch に変更がない場合、ループ検出は停止します。少なくとも 1 つが更新されると、すべての $watch に変更がなくなるまでループが再度トリガーされます。これにより、各モデルが再度変更されなくなります。これはダーティ チェック メカニズムです
controller.js
app.controller('MainCtrl', function() { $scope.name = "Foo"; $scope.changeFoo = function() { $scope.name = "Bar"; } });
index.js
<p>{{ name }}</p> <button ng-click="changeFoo()">Change the name</button>
ボタンを押すと
、ブラウザはイベントを受け取り、Angular コンテキストに入ります。
$digest ループが実行を開始し、各 $watch が変更されるかどうかをクエリします。
$scope.name を監視している $watch が変更を報告するため、別の $digest サイクルが強制されます。
変更が検出されない新しい $digest ループ。
$scope.name の新しい値に対応する DOM の部分を更新します。
$apply
$apply これは、UI の更新として直接理解できます。 イベントがトリガーされたときに $apply を呼び出すと、Angular コンテキストに入ります。呼び出されない場合は入りません。その後の $digest 検出メカニズムはトリガーされません。
app.directive('clickable', function() { return { restrict: "E", scope: { foo: '=' }, template: '<ul style="background-color: lightblue"><li>{{foo}}</li></ul>', link: function(scope, element, attrs) { element.bind('click', function() { scope.foo++; console.log(scope.foo); }); } } });
クリック可能な命令を呼び出すと、foo の値が増加していることがわかりますが、インターフェイスに表示される内容は変化していません。 $digest ダーティ検出メカニズムはトリガーされず、foo を検出する $watch も実行されません。
$apply() メソッドの 2 つの形式
1) パラメーターなし
$scope.$apply();
element.bind('click', function() { scope.foo++; //if error scope.$apply(); });
この形式を使用する場合、scope.$apply の前にプログラムで例外が発生した場合、scope.$apply は実行されず、インターフェースは更新されません
2) パラメータがあります
$scope.$apply(function(){ ... })
element.bind('click', function() { scope.$apply(function() { scope.foo++; }); })
このフォームを使用すると、後から例外が発生してもデータは更新されます。
AngularJS での $watch の使用
一般的な使用法:
$scope.name = 'Hello'; $scope.$watch('name', function(newValue, oldValue) { if (newValue === oldValue) { return; } $scope.updated++; });
传入到$watch()中的第二个参数是一个回调函数,该函数在name的值发生变化的时候会被调用。
如果要监听的是一个对象,那还需要第三个参数:
$scope.data.name = 'Hello'; $scope.$watch('data', function(newValue, oldValue) { if (newValue === oldValue) { return; } $scope.updated++; }, true);
表示比较的是对象的值而不是引用,如果不加第三个参数true,在 data.name 变化时,不会触发相应操作,因为引用的是同一引用。
总结
1) 只有在$scope变量绑定到页面上,才会创建 $watch
2) $apply决定事件是否可以进入angular context
3) $digest 循环检查model时最少两次,最多10次(多于10次抛出异常,防止无限检查)
4) AngularJs自带的指令已经实现了$apply,所以不需要我们额外的编写
5) 在自定义指令时,建议使用带function参数的$apply
上面是我整理给大家的,希望今后会对大家有帮助。
相关文章:
在javaScript中如何使用手机号码校验工具类PhoneUtils
以上がAngularJs で双方向バインディングを使用する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。