首頁  >  文章  >  web前端  >  在AngularJs中如何使用雙向綁定

在AngularJs中如何使用雙向綁定

亚连
亚连原創
2018-06-22 13:45:011334瀏覽

本篇文章主要介紹了淺談AngularJs 雙向綁定原理(資料綁定機制),小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟著小編過來看看吧

那麼什麼是雙向綁定,下面簡單進行講解。

首先我們要理解資料綁定。在我們看到的網站頁面中,是由數據和設計兩部分組合而成。將設計轉換成瀏覽器能理解的語言,便是html和css主要做的工作。而將資料顯示在頁面上,並且有一定的互動效果(例如點擊等使用者操作及對應的頁面反應)則是js主要完成的工作。很多時候我們不可能每次更新數據便刷新頁面(get請求),而是透過向後端請求相關數據,並透過無刷新載入的方式進行更新頁面(post請求)。那麼資料進行更新後,頁面上對應的位置也能自動做出對應的修改,便是資料綁定。

在先前的開發模式中,這一步驟一般透過jq操作DOM結構,從而進行更新頁面。但這樣帶來的是大量的程式碼和大量的操作。如果能在開始的時候,便已經確定好從後端獲取的數據到頁面上需要進行的操作,當數據發生改變,頁面的相關內容也自動發生變化,這樣便能極大地方便前端工程師的開發。在新的框架中(angualr,react,vue等),透過對資料的監視,發現變化便根據已經寫好的規則進行修改頁面,便實現了資料綁定。可以看出,資料綁定是M(model,資料)透過VM(model-view,資料與頁面之間的變換規則)向V(view)的一個修改。

而雙向綁定則是增加了一條反向的路。在使用者操作頁面(例如在Input中輸入值)的時候,資料能及時發生變化,並且根據資料的變化,頁面的另一處也做出對應的修改。有一個常見的例子就是淘寶中的購物車,在商品數量改變的時候,商品價格也能及時變動。這樣便實現了V——M——VM——V的一個雙向綁定。

AngularJs 為 scope 模型上設定了一個 監聽佇列,用來監聽資料變化並更新 view 。每次綁定一個東西到 view(html) 上時 AngularJs 就會往 $watch 佇列插入一條 $watch,用來偵測它監視的 model 裡是否有變化的東西。當瀏覽器接收到可以被 angular context 處理的事件時,$digest 迴圈就會觸發。 $digest 會遍歷所有的 $watch。從而更新DOM。

$watch

這有點類似我們的觀察者模式,在目前作用域$scope下,我們建立一個監視器$watchers和一個監聽器$ watch,$watchers 負責管理所有的$watch,當我們每次綁定到UI上的時候就c858d69dd81008e347cd5f5447f8e393自動e6e38b3c62e8df885fe2e3986461aa63創建一個$watch,並把它放到$watchers。

controller.js

app.controller('MainCtrl', function($scope) {
 $scope.Hello = "Hello";
 $scope.world = "World";
});

index.html

<p>{{Hello}}</p>

這裡,即便我們在$scope上加入了兩個變量,c858d69dd81008e347cd5f5447f8e393但只有一個綁定在了UI上,因此在這裡只生成了一個$watche6e38b3c62e8df885fe2e3986461aa63

#$digest

當瀏覽器接收到可以被angular context處理的事件時,$digest循環就會觸發。 $digest將會遍歷我們的$watch,如果$watch沒有變化,這個循環偵測就將停止,如果有至少一個更新過,這個循環就會再次觸發,直到所有的$watch都沒有變化。這樣就能夠保證每個model都已經不會再改變。這就是髒檢查(Dirty Checking)機制

controller.js

app.controller(&#39;MainCtrl&#39;, function() {
 $scope.name = "Foo";

 $scope.changeFoo = function() {
  $scope.name = "Bar";
 }
});

index.js

<p>{{ name }}</p>
<button ng-click="changeFoo()">Change the name</button>
  1. 當我們按下按鈕

  2. 瀏覽器接收到一個事件,進入angular context。

  3. $digest循環開始執行,查詢每個$watch是否有變化。

  4. 由於監視$scope.name的$watch報告了變化,它會強制再執行一次$digest循環。

  5. 新的$digest循環沒有偵測到變化。

  6. 更新與$scope.name新值對應部分的DOM。

$apply

$apply 我們可以直接理解為刷新UI。 c858d69dd81008e347cd5f5447f8e393如果當事件觸發時,你調用$apply,它會進入angular context,如果沒有呼叫就不會進入,之後的$digest檢測機制就不會觸發e6e38b3c62e8df885fe2e3986461aa63

app.directive(&#39;clickable&#39;, function() {
 return {
  restrict: "E",
  scope: {
  foo: &#39;=&#39;
  },
  template: &#39;<ul style="background-color: lightblue"><li>{{foo}}</li></ul>&#39;,
  link: function(scope, element, attrs) {
  element.bind(&#39;click&#39;, function() {
   scope.foo++;
   console.log(scope.foo);
  });
  }
 }
});

當我們呼叫clickable指令的時候,我們可以看到foo的值增加了,但是介面上顯示的內容並沒有改變。 $digest髒偵測機制沒有觸發,偵測foo的$watch就沒有執行。

$apply()方法的兩種形式

1) 無參考

$scope.$apply();
element.bind(&#39;click&#39;, function() {
 scope.foo++;
 //if error
 scope.$apply();
});

當我們使用這種形式的時候,如果在scope.$apply之前程式發生異常,那scope.$apply沒有執行,介面就不會更新

2) 有參

$scope.$apply(function(){
 ...
})
element.bind(&#39;click&#39;, function() {
 scope.$apply(function() {
  scope.foo++;
 });
})

如果用這種形式,即使後面的發生異常,資料還是會更新。

在 AngularJS 中使用 $watch

常用的使用方式:

$scope.name = &#39;Hello&#39;;
$scope.$watch(&#39;name&#39;, function(newValue, oldValue) {
 if (newValue === oldValue) { return; } 
 $scope.updated++;
});

传入到$watch()中的第二个参数是一个回调函数,该函数在name的值发生变化的时候会被调用。

如果要监听的是一个对象,那还需要第三个参数:

$scope.data.name = &#39;Hello&#39;;
$scope.$watch(&#39;data&#39;, 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

在微信小程序中如何实现下载进度条

在微信小程序中如何使用video组件播放视频

在微信小程序中如何使用audio组件

在微信小程序中有关功能函数总结(详细教程)

以上是在AngularJs中如何使用雙向綁定的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn