国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > JavaScript > 正文

Angularjs中的$apply及優(yōu)化使用詳解

2019-11-19 13:34:54
字體:
來源:轉載
供稿:網(wǎng)友

前言

對于一個在前端屬于純新手的我來說,Javascript都還是一知半解,要想直接上手angular JS,遇到的阻力還真是不少。不過我相信,只要下功夫,即使是反人類的設計也不是什么大的問題。

今天,我們要聊得是Angularjs中的小明星$apply。當我們數(shù)據(jù)更新了,但是view層卻沒反應時,總能聽到有人說,用apply吧,然后,懵懂無知的我們,在賦值代碼后面加了$scope.$apply() ,然后就驚喜的發(fā)現(xiàn)。噢,真的更新了。

然而,有些時候,編譯器會無情的給你返回

Error: $digest already in progress

那么,導致這些現(xiàn)象的原因時什么的呢?$apply究竟干了啥?聽我慢慢到來。

一.$apply的作用

$apply()函數(shù)可以從Angular框架的外部讓表達式在Angular上下文內部執(zhí)行。

上面是AngularJs權威教程中的一句話。什么意思呢?

首先,你要清楚,在原生js或者第三方框架下,修改model,是有可能不會觸發(fā)視圖更新的,比如setTimeout、jquery插件。為什么?因為他們脫離了Angularjs的上下文,Angularjs并不能監(jiān)聽到數(shù)據(jù)的改變。看例子。

1.setTimeout

html:

<p>{{name}}</p>

js:

$scope.name="張三";setTimeout(function(){$scope.name = '李四';//$scope.$apply()},500)

首先,name等于張三,500ms后,我把他賦值為李四,但是,頁面上并沒有改變,依然是張三。

而,我們把$scope.$apply()放開,就正常了,張三成功變?yōu)槔钏摹?/p>

2.第三方插件

html:

<p>Date: <input type="text" id="datepicker"></p><p><header>所選日期</header>{{selectedDate}}</p>

js:

$scope.selectedDate = '';$( function() { $( "#datepicker" ).datepicker({ onClose: function( selectedDate ) { $scope.selectedDate = selectedDate; // $scope.$apply(); } });} );

這是jquery的datepicker插件,當我們選定日期后,下面的日期應該隨之顯現(xiàn),而現(xiàn)在卻沒有。這種情況就必須依靠$apply(),才能更新視圖。

以上兩種情況,都因為不處于Angularjs上下文中,導致監(jiān)聽不到數(shù)據(jù)的變化。而$apply究竟干了什么,才導致數(shù)據(jù)更新正常了呢?

其實$apply相當于一個觸發(fā)器,它的作用就是觸發(fā)digest循環(huán),從而更新視圖。

在digest是Angularjs的核心,是它實現(xiàn)了神奇的數(shù)據(jù)綁定。凡是觸發(fā)事件,必會觸發(fā)digest循環(huán),比如,我們數(shù)值的ng事件,click啊,change,實際上都是觸發(fā)了digest循環(huán)。

所以,我們所做的事,其實就是手動觸發(fā)了digest循環(huán)。關于digest循環(huán),屬于題外話,這里不做過多介紹,想深入了解的同學,可以看看書籍,或者百度。

二.更好地運用digest循環(huán)

在Angularjs中,除了$apply可以觸發(fā)digest循環(huán)外,還有其他的方法,也可以觸發(fā)此循環(huán)。而且$apply往往時最壞的選擇。下面推薦一些更好的選擇。

1.$digest

$scope.$digest()的速度要比$apply要快,因為它只更新當前作用域和子作用域的值,對于父作用域時不管的。而$apply還要評估父作用域,這就大大消耗了性能。

2.$timeout

用$timeout去代替你的setTimeout,$timeout作為Angularjs的自帶服務,當然時更契合Angularjs環(huán)境啦。它會隱性觸發(fā)digest循環(huán),而且它會延遲執(zhí)行,會在上一個digest循環(huán)完成后的下一刻,觸發(fā)digest循環(huán),這樣就不會出現(xiàn)上文所說的

$digest already in progress

我們把setTime的代碼放到$timeout中

$timeout(function(){$scope.name = '李四';},500)

這就能正常工作了,看,沒有討厭的apply了!

3.$evalAsync

最推薦的應該時這個方法了。如果當前正好有一個digest循環(huán)在執(zhí)行,那么它就會把導致digest循環(huán)的操作,放到當前digest循環(huán)中去執(zhí)行。而$timeout是要等到當前digest循環(huán)執(zhí)行完,再執(zhí)行一次digest循環(huán)才可以。所以evalAsync執(zhí)行更快,性能更好。我們可以像$timeout那樣去調用它,即

$scope.$evalAsync(   function( $scope ) {   console.log( "$evalAsync" );   }  );

以上,就是今天要說的全部內容。Angularjs中還藏著許多奧秘,和更好的使用方法,希望大家可以深入地研究,分享出更好的文章。

下面是可執(zhí)行的代碼,大家可以探究探究:https://codepen.io/hanwolfxue/pen/yEZbYQ

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對武林網(wǎng)的支持。

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 呼和浩特市| 会理县| 宽城| 万年县| 舞阳县| 康平县| 高平市| 大姚县| 武夷山市| 嘉荫县| 深州市| 泾阳县| 漠河县| 吉林省| 孝义市| 海城市| 东丽区| 隆尧县| 中江县| 红原县| 获嘉县| 杭锦后旗| 正定县| 澄江县| 景德镇市| 青河县| 卢湾区| 英超| 竹山县| 麻阳| 乌兰察布市| 富民县| 唐山市| 元江| 定远县| 腾冲县| 呼和浩特市| 和田县| 长垣县| 门头沟区| 英吉沙县|