欧美一级特黄大片做受成人-亚洲成人一区二区电影-激情熟女一区二区三区-日韩专区欧美专区国产专区

AngularJS雙向數(shù)據(jù)綁定原理之$watch、$apply和$digest怎么用

小編給大家分享一下AngularJS雙向數(shù)據(jù)綁定原理之$watch、$apply和$digest怎么用,希望大家閱讀完這篇文章之后都有所收獲,下面讓我們一起去探討吧!

成都創(chuàng)新互聯(lián)公司主要從事網(wǎng)站設(shè)計(jì)制作、成都做網(wǎng)站、網(wǎng)頁設(shè)計(jì)、企業(yè)做網(wǎng)站、公司建網(wǎng)站等業(yè)務(wù)。立足成都服務(wù)子洲,10多年網(wǎng)站建設(shè)經(jīng)驗(yàn),價(jià)格優(yōu)惠、服務(wù)專業(yè),歡迎來電咨詢建站服務(wù):18982081108

背景

AngularJS開發(fā)者都想知道雙向數(shù)據(jù)綁定是怎么實(shí)現(xiàn)的。與data-binding相關(guān)的術(shù)語琳瑯滿目: $watch,$apply,$digest,dirty-checking等等它們是如何工作的呢?讓我們從頭開始講起吧

AngularJS 的雙向數(shù)據(jù)綁定是被瀏覽器逼的

瀏覽器看上去很美,其實(shí)在數(shù)據(jù)交互這塊兒,由于瀏覽器的“不作為”,導(dǎo)致瀏覽器的數(shù)據(jù)刷新成為一個(gè)難題。具體來說,瀏覽器可以很容易地監(jiān)聽一個(gè)事件,比如:用戶點(diǎn)擊一個(gè)按鈕,或者在輸入框里輸入東西,為此還提供了事件回調(diào)函數(shù)的API,事件的回調(diào)函數(shù)就會(huì)在javascript解釋器里執(zhí)行;但反過來就沒這么簡單了,如果來自后臺(tái)的數(shù)據(jù)發(fā)生了變化,需要通知給瀏覽器,讓瀏覽器刷新,瀏覽器并沒有提供這樣的數(shù)據(jù)交互機(jī)制,對(duì)于開發(fā)者來說,這是一個(gè)難以逾越的障礙,怎么辦呢? AngularJS出現(xiàn)了,它通過$scope 很好地實(shí)現(xiàn)了雙向數(shù)據(jù)綁定,其背后的原理就是$watch,$apply,$digest,dirty-checking

$watch 隊(duì)列($watch list)

從字面上看,watch 是觀察的意思。 每次綁定一些東西到瀏覽器上時(shí),就會(huì)往$watch隊(duì)列里插入一條$watch。想象一下$watch就是那個(gè)可以檢測它監(jiān)視的model里時(shí)候有變化的東西。例如你有如下的代碼

User: <input type="text" ng-model="user" />
Password: <input type="password" ng-model="pass" />

這里有個(gè)$scope.user,它被綁定在了第一個(gè)輸入框上,還有個(gè)$scope.pass,它被綁定在了第二個(gè)輸入框上;然后在$watch list里面加入兩個(gè)$watch:

創(chuàng)建一個(gè) controllers.js 文件,代碼如下:

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

對(duì)應(yīng)的html 文件, index.html 代碼如下:

Hello, {{ World }}

這里,即便在$scope上添加了兩個(gè)東西,但是只有一個(gè)綁定在了UI上,因此只生成了一個(gè)$watch. 再看下面的例子:

controllers.js

app.controller('MainCtrl', function($scope) {
 $scope.people = [...];
});

對(duì)應(yīng)的html文件 index.html

<ul>
 <li ng-repeat="person in people">
   {{person.name}} - {{person.age}}
 </li>
</ul>

這樣看來,又生成了多個(gè)$watch。每個(gè)person有兩個(gè)(一個(gè)name,一個(gè)age),然后ng-repeat是一個(gè)循環(huán),因此10個(gè)person一共是(2 * 10) +1,也就是說有21個(gè)$watch。 因此,每一個(gè)綁定到了瀏覽器上的數(shù)據(jù)都會(huì)生成一個(gè)$watch。對(duì),那這寫$watch是什么時(shí)候生成的呢? 先回顧下AngularJS的加載原理

AngularJS的加載原理:

AngularJS的模板加載分為編譯(compile)和鏈接(linking)兩個(gè)階段,在linking階段,AngularJS解釋器會(huì)尋找每個(gè)directive,然后生成每個(gè)需要的$watch。對(duì)了,$watch就是在這個(gè)階段生成的。

接下來,開始用到 $digest了

$digest 循環(huán)

從字面上看,digest是 “消化”的意思,總感覺這個(gè)名字怪怪的,跟不可思議的是 dirty-checking, 字面意思“臟檢查”,還是不翻譯為好。原作者的本意肯定不是這個(gè)意思,只可意會(huì)不可言傳!

$digest 是一個(gè)循環(huán),它在循環(huán)做什么呢? $digest 在遍歷我們的$watch。 $digest 一個(gè)個(gè)地詢問$watch —— “嗨,你觀察的數(shù)據(jù)發(fā)生變化了沒?”

這個(gè)遍歷就是所謂的dirty-checking。既然所有的$watch都檢查完了,那就要問了:有沒有$watch更新過?如果有至少一個(gè)更新過,這個(gè)循環(huán)就會(huì)再次觸發(fā),直到所有的$watch都沒有變化。這樣就能夠保證每個(gè)model都已經(jīng)不會(huì)再變化。記住如果循環(huán)超過10次的話,它將會(huì)拋出一個(gè)異常,以免出現(xiàn)無限循環(huán)。 當(dāng)$digest循環(huán)結(jié)束時(shí),DOM相應(yīng)地變化。

看段代碼,例如: controllers.js

app.controller('MainCtrl', function() {
 $scope.name = "Foo";
 $scope.changeFoo = function() {
   $scope.name = "Bar";
 }
});

對(duì)應(yīng)的html文件,index.html

{{ name }}
<button ng-click="changeFoo()">Change the name</button>

這里只有一個(gè)$watch,因?yàn)閚g-click不生成$watch(函數(shù)是不會(huì)變的)。

$digest 執(zhí)行的流程是:

  1. 在瀏覽器按下按鈕;

  2. 瀏覽器接收到一個(gè)事件,進(jìn)入angular context。

  3. $digest循環(huán)開始執(zhí)行,查詢每個(gè)$watch是否變化。

  4. 由于監(jiān)視$scope.name的$watch報(bào)告了變化,它會(huì)強(qiáng)制再執(zhí)行一次$digest循環(huán)。

  5. 新的$digest循環(huán)沒有檢測到變化,此時(shí)瀏覽器拿回控制權(quán),更新與$scope.name新值相應(yīng)部分的DOM。

從中可以看出AngularJS的一個(gè)明顯的不足:每一個(gè)進(jìn)入angular context的事件都會(huì)執(zhí)行一個(gè)$digest循環(huán),哪怕僅僅是輸入一個(gè)字母,$digest 都會(huì)遍歷整個(gè)頁面的所有$watch。

$apply 的應(yīng)用

Angular context 是整個(gè)Angular的上下文,也可以把它理解為Angular容器,那么,是誰來決定哪些事件可以進(jìn)入 Angular Context,哪些事件又不能進(jìn)入呢? 其控制器在 $apply手上。

如果當(dāng)事件觸發(fā)時(shí),調(diào)用$apply,它會(huì)進(jìn)入angular context,如果沒有調(diào)用就不會(huì)進(jìn)入。你可能會(huì)問:剛才的例子并沒有調(diào)用$apply,這是怎么回事呢?原來,是Angular背后替你做了。當(dāng)點(diǎn)擊帶有ng-click的元素時(shí),事件就會(huì)被封裝到一個(gè)$apply調(diào)用中。如果有一個(gè)ng-model="foo"的輸入框,當(dāng)輸入一個(gè)字母 f 時(shí),事件就會(huì)這樣調(diào)用,$apply("foo = 'f';")。

$apply的應(yīng)用場景

$apply是$scope的一個(gè)函數(shù),調(diào)用它會(huì)強(qiáng)制一次$digest循環(huán)。如果當(dāng)前正在執(zhí)行$apply循環(huán),則會(huì)拋出一個(gè)異常。

如果瀏覽器上數(shù)據(jù)沒有及時(shí)刷新,可以通過調(diào)用$scope.$apply() 方法,強(qiáng)行刷新一遍。

通過 $watch 監(jiān)控自己的$scope

<!DOCTYPE html>
<html ng-app="demoApp">
<head>
 <title>test</title>
 <!-- Vendor libraries -->
  <script src="lib/jquery-v1.11.1.js"></script>
  <script src="lib/angular-v1.2.22.js"></script>
  <script src="lib/angular-route-v1.2.22.js"></script>
</head>
<body> 
 <div ng-controller="MainCtrl" >
  <input ng-model="name" />
  Name updated: {{updated}} times.
 </div> 
 <script >
  var demoApp = angular.module('demoApp',[]); 
  demoApp.controller('MainCtrl', function($scope) {
  $scope.name = "Angular";
  $scope.updated = -1;
  $scope.$watch('name', function() {
  $scope.updated++;
 });
});
 </script>
 </body>
</html>

代碼說明:

當(dāng)controller 執(zhí)行到 $watch時(shí),它會(huì)立即調(diào)用一次,所以把updated的值設(shè)為 -1 。 上輸入框中輸入字符發(fā)生變化時(shí),你會(huì)看到 updated 的值隨之變化,而且能顯示變化的次數(shù)。

AngularJS雙向數(shù)據(jù)綁定原理之$watch、$apply和$digest怎么用

$watch 檢測到的數(shù)據(jù)變化

看完了這篇文章,相信你對(duì)“AngularJS雙向數(shù)據(jù)綁定原理之$watch、$apply和$digest怎么用”有了一定的了解,如果想了解更多相關(guān)知識(shí),歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝各位的閱讀!

新聞標(biāo)題:AngularJS雙向數(shù)據(jù)綁定原理之$watch、$apply和$digest怎么用
本文地址:http://aaarwkj.com/article28/ijppjp.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供企業(yè)網(wǎng)站制作、面包屑導(dǎo)航、營銷型網(wǎng)站建設(shè)服務(wù)器托管、App開發(fā)用戶體驗(yàn)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

外貿(mào)網(wǎng)站制作
国精品91人妻一区二区| 婷婷激情六月中文字幕| 91麻豆精品国产综合久久久| 国产免费成人黄视频网站| 国产熟女系列一区二区三区| 少妇被又粗又硬猛烈进视频| 九九在线免费视频蜜臀| 欧美男女精品一区二区三区| 日韩黄片免费观看大全| 免费国产污在线观看网站| 国产三级国产剧情国产av| 国产情侣最新地址在线| 亚洲一区二区三区久久伊人| 国产成年人在线免费观看| 蜜桃网站视频免费观看| 日韩精品欧美精品一区二区| 午夜视频在线观看区一| 国内揄拍国内精品少妇国| 色在色在线播放亚洲中文| 亚洲av综合日韩精品久久| 亚洲欧美日韩国产桃色| 亚洲成人av网址大全| 日韩在线观看视频有码| 色综合色很天天综合色| 成年人在线免费观看国产| 国产一区二区三区午夜视频| 一区二区三区免费视频少妇| 高清美女视频亚洲免费| 国产熟女肥臀精品国产馆乱| 久久久久久国产精品亚洲| 蜜桃午夜精品一区二区三区| 国产精品伦一区二区三级| 亚洲精品熟女av影院| 欧洲一区二区三区黄色| 91欧美日韩在线观看视频| 亚洲精品不卡一区二区| 蜜桃一区二区三区免费| 亚洲综合色视频免费在线播放| 99热这里只有精品最新| 欧美一区二区大香蕉视频| 国产真人免费作爱视频网站|