再談angularJS數(shù)據(jù)綁定機(jī)制及背后原理—angularJS常見(jiàn)問(wèn)題總結(jié)

這篇是對(duì)angularJS的一些疑點(diǎn)回顧俯萎,是對(duì)目前angularJS開(kāi)發(fā)的各種常見(jiàn)問(wèn)題的整理匯總琳轿。如果對(duì)文中的題目全部了然于胸户侥,覺(jué)得對(duì)整個(gè)angular框架應(yīng)該掌握的七七八八了剔猿。希望志同道合的通知補(bǔ)充內(nèi)容

Angular 的數(shù)據(jù)綁定采用什么機(jī)制癞松,詳述原理爽撒?

臟檢查機(jī)制。闡釋臟檢查機(jī)制响蓉,必須先了解如下問(wèn)題硕勿。

單向綁定(ng-bind) 和 雙向綁定(ng-model) 的區(qū)別?

ng-bind 單向數(shù)據(jù)綁定($scope -> view)枫甲,用于數(shù)據(jù)顯示源武,簡(jiǎn)寫(xiě)形式是 {{}}扼褪。

兩者的區(qū)別在于頁(yè)面沒(méi)有加載完畢 {{val}} 會(huì)直接顯示到頁(yè)面,直到 Angular 渲染該綁定數(shù)據(jù)(這種行為有可能將 {{val}} 讓用戶看到)粱栖;而 ng-bind 則是在 Angular 渲染完畢后將數(shù)據(jù)顯示话浇。

ng-model 是雙向數(shù)據(jù)綁定($scope -> view and view -> $scope),用于綁定值會(huì)變化的表單元素等闹究。

雙向數(shù)據(jù)綁定是 AngularJS 的核心機(jī)制之一幔崖。當(dāng) view 中有任何數(shù)據(jù)變化時(shí),會(huì)更新到 model 渣淤,當(dāng) model 中數(shù)據(jù)有變化時(shí)赏寇,view 也會(huì)同步更新,顯然价认,這需要一個(gè)監(jiān)控嗅定。

雙向數(shù)據(jù)綁定的原理?

Angular 在 scope 模型上設(shè)置了一個(gè) 監(jiān)聽(tīng)隊(duì)列刻伊,用來(lái)監(jiān)聽(tīng)數(shù)據(jù)變化并更新 view 露戒。

? 每次綁定一個(gè)東西到 view 上時(shí) AngularJS 就會(huì)往 $watch 隊(duì)列里插入一條 $watch,用來(lái)檢測(cè)它監(jiān)視的 model 里是否有變化的東西捶箱。? ?

當(dāng)你寫(xiě)下表達(dá)式如{{ val }}時(shí)智什,AngularJS在幕后會(huì)為你在scope模型上設(shè)置一個(gè)watcher(表達(dá)式將被 Angular 編譯成一個(gè)監(jiān)視函數(shù)),它用來(lái)在數(shù)據(jù)發(fā)生變化的時(shí)候更新view丁屎。這里的watcher和你會(huì)在AngularJS中設(shè)置的watcher是一樣的:

$scope.$watch('val', function(newValue, oldValue) {

? //update the DOM with newValue

});

將數(shù)據(jù)附加到 Scope 上荠锭,數(shù)據(jù)自身不會(huì)對(duì)性能產(chǎn)生影響,如果沒(méi)有監(jiān)視器來(lái)監(jiān)視這個(gè)屬性晨川,那個(gè)這個(gè)屬性在不在 Scope 上是無(wú)關(guān)重要的证九;Angular 并不會(huì)遍歷 Scope 上的屬性,它將遍歷所有的觀察器共虑。

每個(gè)監(jiān)視函數(shù)是在每次 $digest 過(guò)程中被調(diào)用的愧怜。因此,我們要注意觀察器的數(shù)量以及每個(gè)監(jiān)視函數(shù)或者監(jiān)視表達(dá)式的性能妈拌。

$digest循環(huán)是在什么時(shí)候以各種方式開(kāi)始的拥坛?

當(dāng)瀏覽器接收到可以被 angular context 處理的事件時(shí),$digest 循環(huán)就會(huì)觸發(fā)尘分,遍歷所有的 $watch猜惋,最后更新 dom。

舉個(gè)栗子

increase 1

click 時(shí)會(huì)產(chǎn)生一次更新的操作(至少觸發(fā)兩次 $digest 循環(huán))

按下按鈕

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

$digest 循環(huán)開(kāi)始執(zhí)行著摔,查詢每個(gè) $watch 是否變化

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

新的 $digest 循環(huán)未檢測(cè)到變化

瀏覽器拿回控制器定续,更新 $scope. val.新值對(duì)應(yīng)的 dom

在調(diào)用了$scope.$digest()后谍咆,$digest循環(huán)就開(kāi)始了禾锤。假設(shè)你在一個(gè)ng-click指令對(duì)應(yīng)的handler函數(shù)中更改了scope中的一條數(shù)據(jù),此時(shí)AngularJS會(huì)自動(dòng)地通過(guò)調(diào)用$digest()來(lái)觸發(fā)一輪$digest循環(huán)卧波。當(dāng)$digest循環(huán)開(kāi)始后时肿,它會(huì)觸發(fā)每個(gè)watcher。這些watchers會(huì)檢查scope中的當(dāng)前model值是否和上一次計(jì)算得到的model值不同港粱。如果不同螃成,那么對(duì)應(yīng)的回調(diào)函數(shù)會(huì)被執(zhí)行。調(diào)用該函數(shù)的結(jié)果查坪,就是view中的表達(dá)式內(nèi)容(譯注:諸如{{ val }})會(huì)被更新寸宏。除了ng-click指令,還有一些其它的built-in指令以及服務(wù)來(lái)讓你更改models(比如ng-model偿曙,$timeout等)和自動(dòng)觸發(fā)一次$digest循環(huán)氮凝。

目前為止還不錯(cuò)!但是望忆,有一個(gè)小問(wèn)題罩阵。在上面的例子中,AngularJS并不直接調(diào)用$digest()启摄,而是調(diào)用$scope.$apply()稿壁,后者會(huì)調(diào)用$rootScope.$digest()。因此歉备,一輪$digest循環(huán)在$rootScope開(kāi)始傅是,隨后會(huì)訪問(wèn)到所有的children scope中的watchers。

通常寫(xiě)代碼時(shí)我們無(wú)需主動(dòng)調(diào)用 $apply 或 $digest 是因?yàn)?angular 在外部對(duì)我們的回調(diào)函數(shù)做了包裝蕾羊。例如常用的 ng-click喧笔,這是一個(gè)指令(Directive),內(nèi)部實(shí)現(xiàn)則 類(lèi)似 于

DOM.addEventListener('click', function ($scope) {

? $scope.$apply(() => userCode());

});

可以看到:ng-click 幫我們做了 $apply 這個(gè)操作龟再。類(lèi)似的不只是這些事件回調(diào)函數(shù)书闸,還有 $http、$timeout 等利凑。我聽(tīng)很多人抱怨說(shuō) angular 這個(gè)庫(kù)太大了什么都管浆劲,其實(shí)你可以不用它自帶的這些服務(wù)(Service),只要你記得手工調(diào)用 $scope.$apply截碴。

現(xiàn)在,假設(shè)你將ng-click指令關(guān)聯(lián)到了一個(gè)button上蛉威,并傳入了一個(gè)function名到ng-click上日丹。當(dāng)該button被點(diǎn)擊時(shí),AngularJS會(huì)將此function包裝到一個(gè)wrapping function中蚯嫌,然后傳入到$scope.$apply()哲虾。因此丙躏,你的function會(huì)正常被執(zhí)行,修改models(如果需要的話)束凑,此時(shí)一輪$digest循環(huán)也會(huì)被觸發(fā)晒旅,用來(lái)確保view也會(huì)被更新。

Note: $scope.$apply()會(huì)自動(dòng)地調(diào)用$rootScope.$digest()汪诉。$apply()方法有兩種形式废恋。第一種會(huì)接受一個(gè)function作為參數(shù),執(zhí)行該function并且觸發(fā)一輪$digest循環(huán)扒寄。第二種會(huì)不接受任何參數(shù)鱼鼓,只是觸發(fā)一輪$digest循環(huán)。我們馬上會(huì)看到為什么第一種形式更好该编。

$digest 循環(huán)會(huì)運(yùn)行多少次迄本?

$digest 循環(huán)的上限是 10 次(超過(guò) 10次后拋出一個(gè)異常,防止無(wú)限循環(huán))课竣。

$digest 循環(huán)不會(huì)只運(yùn)行一次嘉赎。在當(dāng)前的一次循環(huán)結(jié)束后,它會(huì)再執(zhí)行一次循環(huán)用來(lái)檢查是否有 models 發(fā)生了變化于樟。

這就是臟檢查(Dirty Checking)公条,它用來(lái)處理在 listener 函數(shù)被執(zhí)行時(shí)可能引起的 model 變化。因此 $digest 循環(huán)會(huì)持續(xù)運(yùn)行直到 model 不再發(fā)生變化隔披,或者 $digest 循環(huán)的次數(shù)達(dá)到了 10 次(超過(guò) 10 次后拋出一個(gè)異常赃份,防止無(wú)限循環(huán))。

當(dāng) $digest 循環(huán)結(jié)束時(shí)奢米,DOM 相應(yīng)地變化抓韩。

臟檢查如何被觸發(fā)?

angular 會(huì)在可能觸發(fā) UI 變更的時(shí)候進(jìn)行臟檢查:這句話并不準(zhǔn)確鬓长。實(shí)際上谒拴,

臟檢查是digest執(zhí)行的,另一個(gè)更常用的用于觸發(fā)臟檢查的函數(shù)apply——其實(shí)就是 $digest 的一個(gè)簡(jiǎn)單封裝(還做了一些抓異常的工作)涉波。

通常寫(xiě)代碼時(shí)我們無(wú)需主動(dòng)調(diào)用 $apply 或 $digest 是因?yàn)?angular 在外部對(duì)我們的回調(diào)函數(shù)做了包裝英上。例如常用的 ng-click,這是一個(gè)指令(Directive)啤覆,內(nèi)部實(shí)現(xiàn)則 類(lèi)似于

DOM.addEventListener('click', function ($scope) {

? $scope.$apply(() => userCode());

});

angular對(duì)常用的dom事件苍日,xhq事件作了封裝,如果調(diào)用這些封裝窗声,就會(huì)在里面觸發(fā)進(jìn)入angular的digest流程相恃,主要有以下情況:

DOM事件,如用戶輸入文本笨觅,點(diǎn)擊按鈕等拦耐,(ng-click)

XHQ響應(yīng)事件($http)

瀏覽器Location變更事件耕腾,即Url中hash部分變更($location)

Timer事件($Timeout,$interval)

手動(dòng)調(diào)用$apply或$digest

$apply() 和$digest() 的區(qū)別?

$apply 是 $scope(或者是 direcvie 里的 link 函數(shù)中的 scope)的一個(gè)函數(shù)杀糯,調(diào)用它會(huì)強(qiáng)制一次 $digest 循環(huán)(除非當(dāng)前正在執(zhí)行循環(huán)扫俺,這種情況下會(huì)拋出一個(gè)異常,這是我們不需要在那里執(zhí)行 $apply 的標(biāo)志)固翰。

$apply() 和 $digest() 有兩個(gè)區(qū)別狼纬。

1) 最直接的差異是, $apply 可以帶參數(shù)倦挂,它可以接受一個(gè)函數(shù)畸颅,然后在應(yīng)用數(shù)據(jù)之后,調(diào)用這個(gè)函數(shù)方援。所以没炒,一般在集成非 Angular 框架(比如jQuery)的代碼時(shí),可以把代碼寫(xiě)在這個(gè)里面調(diào)用犯戏。

2) 當(dāng)調(diào)用 $digest 的時(shí)候送火,只觸發(fā)當(dāng)前作用域和它的子作用域上的監(jiān)控,但是當(dāng)調(diào)用 $apply 的時(shí)候先匪,會(huì)觸發(fā)作用域樹(shù)上的所有監(jiān)控种吸。

什么時(shí)候手動(dòng)調(diào)用 $apply() 方法?

取決于是否在 Angular 上下文環(huán)境(angular context)呀非。

AngularJS對(duì)此有著非常明確的要求坚俗,就是它只負(fù)責(zé)對(duì)發(fā)生于AngularJS上下文環(huán)境中的變更會(huì)做出自動(dòng)地響應(yīng)(即,在$apply()方法中發(fā)生的對(duì)于models的更改)岸裙。AngularJS的built-in指令就是這樣做的猖败,所以任何的model變更都會(huì)被反映到view中。但是降允,如果你在AngularJS上下文之外的任何地方修改了model恩闻,那么你就需要通過(guò)手動(dòng)調(diào)用$apply()來(lái)通知AngularJS。這就像告訴AngularJS剧董,你修改了一些models幢尚,希望AngularJS幫你觸發(fā)watchers來(lái)做出正確的響應(yīng)。

典型的需要調(diào)用 $apply() 方法的場(chǎng)景是:

1) 使用了 JavaScript 中的 setTimeout() 來(lái)更新一個(gè) scope model

2) 用指令設(shè)置一個(gè) DOM 事件 listener 并且在該 listener 中修改了一些 models

場(chǎng)景一

$scope.setMsg = function() {

? ? setTimeout(function() {

? ? ? ? $scope.message = 'hello world';

? ? ? ? console.log('message:' + $scope.message);

? ? }, 2000);

}

$scope.setMsg();

運(yùn)行這個(gè)例子翅楼,會(huì)看到過(guò)了兩秒鐘之后尉剩,控制臺(tái)確實(shí)會(huì)顯示出已經(jīng)更新的 model,然而毅臊,view 并沒(méi)有更新理茎。

在 $scope.getMessage 加入 $apply() 方法。

$scope.getMessage = function() {

? ? setTimeout(function() {

? ? ? ? $scope.$apply(function() {

? ? ? ? ? ? $scope.message = 'hello world';

? ? ? ? ? ? console.log('message:' + $scope.message);

? ? ? ? });

? ? }, 2000);

}

再運(yùn)行就 OK 了。

不過(guò)功蜓,在 AngularJS 中應(yīng)該盡量使用 $timeout Service 來(lái)代替 setTimeout(),因?yàn)榍罢邥?huì)幫你調(diào)用 $apply()宠蚂,讓你不需要手動(dòng)地調(diào)用它式撼。

場(chǎng)景二

實(shí)現(xiàn)一個(gè) click 的指令,類(lèi)似以下功能,directive 的編寫(xiě)如下:

app.directive("inc", function() {

? ? return function (scope, element, attr) {

? ? ? ? element.on("click", function() {

? ? ? ? ? ? scope.val++;

? ? ? ? });

? ? };

});

跟場(chǎng)景一的結(jié)果一樣求厕,這個(gè)時(shí)候著隆,點(diǎn)擊按鈕,界面上的數(shù)字并不會(huì)增加呀癣。但查看調(diào)試器美浦,發(fā)現(xiàn)數(shù)據(jù)確實(shí)已經(jīng)增加了。

在 scope.val++; 一行后面添加 scope.$apply(); 或者 scope.$digest(); 就 OK 了项栏。

$apply() 方法的兩種形式

//無(wú)參

$scope.$apply()

//有參

$scope.$apply(function(){

? ? ...

})

應(yīng)該總使用接受一個(gè) function 作為參數(shù)的 $apply() 方法浦辨。這是因?yàn)楫?dāng)傳入一個(gè) function 到 $apply() 中的時(shí)候,這個(gè) function 會(huì)被包裝到一個(gè) try…catch 塊中沼沈,所以一旦有異常發(fā)生流酬,該異常會(huì)被 $exceptionHandler service 處理。

想象一下如果有個(gè) alert 框顯示錯(cuò)誤給用戶列另,然后有個(gè)第三方的庫(kù)進(jìn)行一個(gè)網(wǎng)絡(luò)調(diào)用然后失敗了芽腾,如果不把它封裝進(jìn) $apply 里面,Angular 永遠(yuǎn)不會(huì)知道失敗了页衙,alert 框就永遠(yuǎn)不會(huì)彈出來(lái)了摊滔。

在 AngularJS 中使用 $watch注意事項(xiàng)?

如果要監(jiān)聽(tīng)的是一個(gè)對(duì)象店乐,那還需要第三個(gè)參數(shù)

$scope.data.name = 'htf';

$scope.$watch('data', function(newValue, oldValue) {

? ? if (newValue === oldValue) { return; }

? ? $scope.updated++;

}, true);

表示比較的是對(duì)象的值而不是引用艰躺,如果不加第三個(gè)參數(shù) true ,在 data.name 變化時(shí)响巢,不會(huì)觸發(fā)相應(yīng)操作描滔,因?yàn)橐玫氖峭灰谩?/p>

臟檢查的范圍

前面說(shuō)到:angular 會(huì)對(duì)所有綁定到 UI 上的表達(dá)式做臟檢查。其實(shí)踪古,在 angular 實(shí)現(xiàn)內(nèi)部含长,所有綁定表達(dá)式都被轉(zhuǎn)換為 $scope.$watch()。每個(gè) $watch 記錄了上一次表達(dá)式的值伏穆。有 ng-bind="a" 即有 $scope.$watch('a', callback)拘泞,而 $scope.$watch 可不會(huì)管被 watch 的表達(dá)式是否跟觸發(fā)臟檢查的事件有關(guān)。

例如:

?

TEST

問(wèn):點(diǎn)擊 TEST 這個(gè)按鈕時(shí)會(huì)觸發(fā)臟檢查嗎枕扫?觸發(fā)幾次陪腌?

首先:ng-click="" 什么都沒(méi)有做。angular 會(huì)因?yàn)檫@個(gè)事件回調(diào)函數(shù)什么都沒(méi)做就不進(jìn)行臟檢查嗎?不會(huì)诗鸭。

然后:#span1 被隱藏掉了染簇,會(huì)檢查綁定在它上面的表達(dá)式嗎?盡管用戶看不到强岸,但是 $scope.$watch('content', callback) 還在锻弓。就算你直接把這個(gè) span 元素干掉,只要 watch 表達(dá)式還在蝌箍,要檢查的還會(huì)檢查青灼。

再次:重復(fù)的表達(dá)式會(huì)重復(fù)檢查嗎?會(huì)妓盲。

最后:別忘了 ng-show="false"杂拨。可能是因?yàn)?angular 的開(kāi)發(fā)人員認(rèn)為這種綁定常量的情況并不多見(jiàn)悯衬,所以 $watch 并沒(méi)有識(shí)別所監(jiān)視的表達(dá)式是否是常量弹沽。常量依舊會(huì)重復(fù)檢查。

所以:

答:觸發(fā)三次筋粗。一次 false贷币,一次 content,一次 content

所以說(shuō)一個(gè)綁定表達(dá)式只要放在當(dāng)前 DOM 樹(shù)里就會(huì)被監(jiān)視亏狰,不管它是否可見(jiàn)役纹,不管它是否被放在另一個(gè) Tab 里,更不管它是否與用戶操作相關(guān)暇唾。

另外促脉,就算在不同 Controller 里構(gòu)造的 $scope 也會(huì)互相影響,別忘了 angular 還有全局的 $rootScope策州,你還可以 $scope.$emit瘸味。angular 無(wú)法保證你絕對(duì)不會(huì)在一個(gè) controller 里更改另一個(gè) controller 生成的 scope,包括 自定義指令(Directive)生成的 scope 和 Angular 1.5 里新引入的組件(Component)够挂。

所以說(shuō)不要懷疑用戶在輸入表單時(shí) angular 會(huì)不會(huì)監(jiān)聽(tīng)頁(yè)面左邊導(dǎo)航欄的變化旁仿。

如何優(yōu)化臟檢查與運(yùn)行效率

臟檢查慢嗎?

說(shuō)實(shí)話臟檢查效率是不高孽糖,但是也談不上有多慢枯冈。簡(jiǎn)單的數(shù)字或字符串比較能有多慢呢?十幾個(gè)表達(dá)式的臟檢查可以直接忽略不計(jì)办悟;上百個(gè)也可以接受尘奏;成百上千個(gè)就有很大問(wèn)題了。綁定大量表達(dá)式時(shí)請(qǐng)注意所綁定的表達(dá)式效率病蛉。建議注意一下幾點(diǎn):

表達(dá)式(以及表達(dá)式所調(diào)用的函數(shù))中少寫(xiě)太過(guò)復(fù)雜的邏輯

不要連接太長(zhǎng)的 filter(往往 filter 里都會(huì)遍歷并且生成新數(shù)組)

不要訪問(wèn) DOM 元素炫加。

1瑰煎、使用單次綁定減少綁定表達(dá)式數(shù)量 單次綁定(One-time binding 是 Angular 1.3 就引入的一種特殊的表達(dá)式,它以 :: 開(kāi)頭俗孝,當(dāng)臟檢查發(fā)現(xiàn)這種表達(dá)式的值不為 undefined 時(shí)就認(rèn)為此表達(dá)式已經(jīng)穩(wěn)定酒甸,并取消對(duì)此表達(dá)式的監(jiān)視。這是一種行之有效的減少綁定表達(dá)式數(shù)量的方法赋铝,與 ng-repeat 連用效果更佳(下文會(huì)提到)烘挫,但過(guò)度使用也容易引發(fā) bug。

2柬甥、善用 ng-if 減少綁定表達(dá)式的數(shù)量

如果你認(rèn)為 ng-if 就是另一種用于隱藏、顯示 DOM 元素的方法你就大錯(cuò)特錯(cuò)了其垄。

ng-if 不僅可以減少 DOM 樹(shù)中元素的數(shù)量(而非像 ng-hide 那樣僅僅只是加個(gè) display: none)苛蒲,每一個(gè) ng-if 擁有自己的 scope,ng-if 下面的 $watch 表達(dá)式都是注冊(cè)在 ng-if 自己 scope 中绿满。當(dāng) ng-if 變?yōu)?false臂外,ng-if 下的 scope 被銷(xiāo)毀,注冊(cè)在這個(gè) scope 里的綁定表達(dá)式也就隨之銷(xiāo)毀了喇颁。

考慮這種 Tab 選項(xiàng)卡實(shí)現(xiàn):

    ?

  • Tab 1 title
  • ?

  • Tab 2 title
  • ?

  • Tab 3 title
  • ?

  • Tab 4 title
  • [[Tab 1 body...]]

    [[Tab 2 body...]]

    [[Tab 3 body...]]

    [[Tab 4 body...]]

    對(duì)于這種會(huì)反復(fù)隱藏漏健、顯示的元素,通常人們第一反應(yīng)都是使用 ng-show 或 ng-hide 簡(jiǎn)單的用 display: none 把元素設(shè)置為不可見(jiàn)橘霎。

    然而入上文所說(shuō)蔫浆,肉眼不可見(jiàn)不代表不會(huì)跑臟檢查。如果將 ng-show 替換為 ng-if 或 ng-switch-when

    [[Tab 1 body...]]

    [[Tab 2 body...]]

    [[Tab 3 body...]]

    [[Tab 4 body...]]

    有如下優(yōu)點(diǎn):

    首先 DOM 樹(shù)中的元素個(gè)數(shù)顯著減少至四分之一姐叁,降低內(nèi)存占用

    其次 $watch 表達(dá)式也減少至四分之一瓦盛,提升臟檢查循環(huán)的速度

    如果這個(gè) tab 下面有 controller(例如每個(gè) tab 都被封裝為一個(gè)組件),那么僅當(dāng)這個(gè) tab 被選中時(shí)該 controller 才會(huì)執(zhí)行外潜,可以減少各頁(yè)面的互相干擾

    如果 controller 中調(diào)用接口獲取數(shù)據(jù)原环,那么僅當(dāng)對(duì)應(yīng) tab 被選中時(shí)才會(huì)加載,避免網(wǎng)絡(luò)擁擠

    當(dāng)然也有缺點(diǎn):

    DOM 重建本身費(fèi)時(shí)間

    如果 tab 下有 controller处窥,那么每次該 tab 被選中時(shí) controller 都會(huì)被執(zhí)行

    如果在 controller 里面調(diào)接口獲取數(shù)據(jù)嘱吗,那么每次該 tab 被選中時(shí)都會(huì)重新加載

    各位讀者自己取舍。

    3滔驾、給 ng-repeat 手工添加 track by

    不恰當(dāng)?shù)?ng-repeat 會(huì)造成 DOM 樹(shù)反復(fù)重新構(gòu)造谒麦,拖慢瀏覽器響應(yīng)速度,造成頁(yè)面閃爍哆致。除了上面這種比較極端的情況弄匕,如果一個(gè)列表頻繁拉取 Server 端數(shù)據(jù)自刷新的話也一定要手工添加 track by,因?yàn)榻涌诮o前端的數(shù)據(jù)是不可能包含 $$hashKey 這種東西的沽瞭,于是結(jié)果就造成列表頻繁的重建迁匠。

    其實(shí)不必考慮那么多,總之加上沒(méi)壞處,至少可以避免 angular 生成 $$hashKey 這種奇奇怪怪的東西城丧。

    具體參看: 詳解track by

    臟檢測(cè)的利弊延曙?

    很多人對(duì)Angular的臟檢測(cè)機(jī)制感到不屑,推崇基于setter亡哄,getter的觀測(cè)機(jī)制枝缔,在我看來(lái),這只是同一個(gè)事情的不同實(shí)現(xiàn)方式蚊惯,并沒(méi)有誰(shuí)完全勝過(guò)誰(shuí)愿卸,兩者是各有優(yōu)劣的。

    大家都知道截型,在循環(huán)中批量添加DOM元素的時(shí)候趴荸,會(huì)推薦使用DocumentFragment,為什么呢宦焦,因?yàn)槿绻看味紝?duì)DOM產(chǎn)生變更发钝,它都要修改DOM樹(shù)的結(jié)構(gòu),性能影響大波闹,如果我們能先在文檔碎片中把DOM結(jié)構(gòu)創(chuàng)建好酝豪,然后整體添加到主文檔中,這個(gè)DOM樹(shù)的變更就會(huì)一次完成精堕,性能會(huì)提高很多孵淘。

    同理,在Angular框架里歹篓,考慮到這樣的場(chǎng)景:

    function TestCtrl($scope) {

    ? ? $scope.numOfCheckedItems = 0;

    ? ? var list = [];

    ? ? for (var i=0; i<10000; i++) {

    ? ? ? ? list.push({

    ? ? ? ? ? ? index: i,

    ? ? ? ? ? ? checked: false

    ? ? ? ? });

    ? ? }

    ? ? $scope.list = list;

    ? ? $scope.toggleChecked = function(flag) {

    ? ? ? ? for (var i=0; i

    ? ? ? ? ? ? list[i].checked = flag;

    ? ? ? ? ? ? $scope.numOfCheckedItems++;

    ? ? ? ? }

    ? ? };

    }

    如果界面上某個(gè)文本綁定這個(gè)numOfCheckedItems夺英,會(huì)怎樣?在臟檢測(cè)的機(jī)制下滋捶,這個(gè)過(guò)程毫無(wú)壓力痛悯,一次做完所有數(shù)據(jù)變更,然后整體應(yīng)用到界面上重窟。這時(shí)候载萌,基于setter的機(jī)制就慘了,除非它也是像Angular這樣把批量操作延時(shí)到一次更新巡扇,否則性能會(huì)更低扭仁。

    所以說(shuō),兩種不同的監(jiān)控方式厅翔,各有其優(yōu)缺點(diǎn)乖坠,最好的辦法是了解各自使用方式的差異,考慮出它們性能的差異所在刀闷,在不同的業(yè)務(wù)場(chǎng)景中熊泵,避開(kāi)最容易造成性能瓶頸的用法仰迁。

    ng-if跟ng-show/hide的區(qū)別有哪些?

    第一點(diǎn)區(qū)別是顽分,ng-if 在后面表達(dá)式為 true 的時(shí)候才創(chuàng)建這個(gè) dom 節(jié)點(diǎn)徐许,ng-show 是初始時(shí)就創(chuàng)建了,用 display:block 和 display:none 來(lái)控制顯示和不顯示卒蘸。第二點(diǎn)區(qū)別是雌隅,ng-if 會(huì)(隱式地)產(chǎn)生新作用域,ng-switch 缸沃、 ng-include 等會(huì)動(dòng)態(tài)創(chuàng)建一塊界面的也是如此恰起。

    ng-repeat迭代數(shù)組的時(shí)候,如果數(shù)組中有相同值趾牧,會(huì)有什么問(wèn)題检盼,如何解決?

    會(huì)提示 Duplicates in a repeater are not allowed. 加 track by $index 可解決武氓。當(dāng)然,也可以 trace by 任何一個(gè)普通的值仇箱,只要能唯一性標(biāo)識(shí)數(shù)組中的每一項(xiàng)即可(建立 dom 和數(shù)據(jù)之間的關(guān)聯(lián))县恕。

    ng-click中寫(xiě)的表達(dá)式,能使用JS原生對(duì)象上的方法剂桥,比如Math.max之類(lèi)的嗎?為什么权逗?

    不可以美尸。只要是在頁(yè)面中,就不能直接調(diào)用原生的 JS 方法斟薇,因?yàn)檫@些并不存在于與頁(yè)面對(duì)應(yīng)的 Controller 的 $scope 中师坎。除非在 $scope 中添加了這個(gè)函數(shù):

    $scope.parseInt = function(x){

    ? ? return parseInt(x);

    }

    {{now | 'yyyy-MM-dd'}}這種表達(dá)式里面,豎線和后面的參數(shù)通過(guò)什么方式可以自定義堪滨?

    定義方式:

    app.filter('過(guò)濾器名稱(chēng)',function(){

    ? ? return function(需要過(guò)濾的對(duì)象, 過(guò)濾器參數(shù)1, 過(guò)濾器參數(shù)2, ...){

    ? ? ? ? //...做一些事情

    ? ? ? ? return 處理后的對(duì)象;

    ? ? }

    });

    使用方式有兩種胯陋,一種是直接在頁(yè)面里:

    {{now | date : 'yyyy-MM-dd'}}

    一種是在 js 里面用:

    // $filter('過(guò)濾器名稱(chēng)')(需要過(guò)濾的對(duì)象, 參數(shù)1, 參數(shù)2,...)

    $filter('date')(now, 'yyyy-MM-dd hh:mm:ss');

    factory和service,provider是什么關(guān)系袱箱?

    factory 把 service 的方法和數(shù)據(jù)放在一個(gè)對(duì)象里遏乔,并返回這個(gè)對(duì)象;service 通過(guò)構(gòu)造函數(shù)方式創(chuàng)建 service发笔,返回一個(gè)實(shí)例化對(duì)象盟萨;provider 創(chuàng)建一個(gè)可通過(guò) config 配置的 service。從底層實(shí)現(xiàn)上來(lái)看了讨,service 調(diào)用了 factory捻激,返回其實(shí)例制轰;factory 調(diào)用了 provider,將其定義的內(nèi)容放在 $get 中返回铺罢。factory 和 service 功能類(lèi)似艇挨,只不過(guò) factory 是普通 function,可以返回任何東西(return 的都可以被訪問(wèn)韭赘,所以那些私有變量怎么寫(xiě)你懂的)缩滨;service 是構(gòu)造器,可以不返回(綁定到 this 的都可以被訪問(wèn))泉瞻;provider 是加強(qiáng)版 factory脉漏,返回一個(gè)可配置的 factory。

    詳述angular的“依賴注入”

    AngularJS 是通過(guò)構(gòu)造函數(shù)的參數(shù)名字來(lái)推斷依賴服務(wù)名稱(chēng)的袖牙,通過(guò) toString() 來(lái)找到這個(gè)定義的 function 對(duì)應(yīng)的字符串侧巨,然后用正則解析出其中的參數(shù)(依賴項(xiàng)),再去依賴映射中取到對(duì)應(yīng)的依賴鞭达,實(shí)例化之后傳入司忱。因?yàn)?AngularJS 的 injector 是假設(shè)函數(shù)的參數(shù)名就是依賴的名字,然后去查找依賴項(xiàng)畴蹭,那如果像下面這樣簡(jiǎn)單注入依賴坦仍,代碼壓縮后(參數(shù)被重命名了),就無(wú)法查找到依賴項(xiàng)了叨襟。

    function myCtrl = ($scope, $http){

    ? ? ...}

    所以繁扎,通常會(huì)使用下面兩種方式注入依賴(對(duì)依賴添加的順序有要求)。

    數(shù)組注釋法:

    myApp.controller('myCtrl', ['$scope', '$http', function($scope, $http){

    ? ? ...

    }])

    顯式 $inject :

    myApp.controller('myCtrl', myCtrl);

    function myCtrl = ($scope, $http){

    ? ? ...

    }

    myCtrl.$inject = ['$scope', '$http'];

    對(duì)于一個(gè) DI 容器糊闽,必須具備三個(gè)要素:依賴項(xiàng)的注冊(cè)梳玫,依賴關(guān)系的聲明和對(duì)象的獲取。在 AngularJS 中右犹,module 和 $provide 都可以提供依賴項(xiàng)的注冊(cè)提澎;內(nèi)置的 injector 可以獲取對(duì)象(自動(dòng)完成依賴注入);依賴關(guān)系的聲明念链,就是上面的那兩種方式虱朵。

    html: {{currentDate()}} js: $scope.currentDate = function(){return new Date();} 這種寫(xiě)法有沒(méi)有問(wèn)題

    有問(wèn)題,時(shí)間是實(shí)時(shí)變化的钓账,然后會(huì)一直更新數(shù)據(jù)碴犬,效率低,臟數(shù)據(jù)檢查到10次之后不再繼續(xù)檢查;

    解決方案:可以使用一個(gè)變量來(lái)接收函數(shù)調(diào)用

    controller as 和controller 有什么區(qū)別梆暮,能解決什么問(wèn)題?

    在使用controller的時(shí)候服协,為控制器注入$window與$scope,這個(gè)時(shí)候controller中的屬性與方法是屬于$scope的啦粹,而使用controllerAS的時(shí)候偿荷,可以將controller定義為Javascript的原型類(lèi)窘游,在html中直接綁定原型類(lèi)的屬性和方法

    優(yōu)點(diǎn):

    可以使用 Javascript 的原型類(lèi), 我們可以使用更加高級(jí)的 ES6 或者 TypeScript 來(lái)編寫(xiě) Controller 跳纳;

    指代清晰忍饰。在嵌套scope時(shí),子scope如果想使用父scope的屬性寺庄,只需簡(jiǎn)單的使用父scope的別名引用父scope即可艾蓝。

    避開(kāi)了所謂的 child scope 原型繼承帶來(lái)的一些問(wèn)題(原來(lái)別名ctrl就是定義在$scope上的一個(gè)對(duì)象,這就是controller的一個(gè)實(shí)例斗塘,所有在JS中定義controller時(shí)綁定到this上的model其實(shí)都是綁定到$scope.ctrl上的赢织。使用controller as的一大好處就是原型鏈繼承給scope帶來(lái)的問(wèn)題都不復(fù)存在了,即有效避免了在嵌套scope的情況下子scope的屬性隱藏掉父scope屬性的情況馍盟。)

    controller的定義不依賴$scope于置。

    定義controller時(shí)不用顯式的依賴$scope,這有什么好處呢贞岭?仔細(xì)看定義八毯,這不就是一個(gè)普通的函數(shù)定義嘛,對(duì)瞄桨!這就是好處话速!例子中的ScopeController就是所謂的POJO(Plain Old Javascript Object,Java里偷來(lái)的概念)讲婚,這樣的Object與框架無(wú)關(guān)尿孔,里面只有邏輯俊柔。所以即便有一天你的項(xiàng)目不再使用AngularJS了筹麸,依然可以很方便的重用和移植這些邏輯。另外雏婶,從測(cè)試的角度看物赶,這樣的Object也是單元測(cè)試友好的。單元測(cè)試強(qiáng)調(diào)的就是孤立其他依賴元素留晚,而POJO恰恰滿足這個(gè)條件酵紫,可以單純的去測(cè)試這個(gè)函數(shù)的輸入輸出,而不用費(fèi)勁的去模擬一個(gè)假的$scope错维。

    防止濫用$scope的$watch,$on,$broadcast方法退疫∏看欤可能剛剛就有人想問(wèn)了,不依賴$scope我怎么watch一個(gè)model隆判,怎樣廣播和響應(yīng)事件犬庇。答案是沒(méi)法弄僧界,這些事還真是只有$scope能干。但很多時(shí)候在controller里watch一個(gè)model是很多余的臭挽,這樣做會(huì)明顯的降低性能捂襟。所以,當(dāng)你本來(lái)就依賴$scope的時(shí)候欢峰,你會(huì)習(xí)慣性的調(diào)用這些方法來(lái)實(shí)現(xiàn)自己的邏輯葬荷。但當(dāng)使用controller as的時(shí)候,由于沒(méi)有直接依賴$scope赤赊,使用watch前你會(huì)稍加斟酌闯狱,沒(méi)準(zhǔn)就思考到了別的實(shí)現(xiàn)方式了呢。

    定義route時(shí)也能用controller as抛计。除了在DOM中顯式的指明ng-controller哄孤,還有一種情況是controller的綁定是route里定義好的,那這時(shí)能使用controller as嗎吹截?答案是肯定的瘦陈,route提供了一個(gè)controllerAs參數(shù)。這樣在模板里就可以直接使用別名home啦波俄。

    個(gè)人覺(jué)得還是偏向于使用controller as的晨逝,當(dāng)然有一點(diǎn)要澄清,使用contoller as并沒(méi)有什么性能上的提升懦铺,僅僅是一種好的習(xí)慣罷了捉貌。

    無(wú)論定義controller時(shí)有沒(méi)有直接依賴$scope,DOM中的scope是始終存在的冬念。即使使用controller as趁窃,雙向綁定還是通過(guò)$scope的watch以及digest來(lái)實(shí)現(xiàn)的。

    請(qǐng)簡(jiǎn)述$compile的用法急前?

    angularjs里比較重要但又很少手動(dòng)調(diào)用的要屬$compile服務(wù)了醒陆,通常在寫(xiě)組件或指令時(shí),都是angularjs自動(dòng)編譯完成的裆针,但有時(shí)我們可能需要手動(dòng)編譯刨摩,比如封裝一個(gè)table組件,根據(jù)參數(shù)實(shí)現(xiàn)自定義渲染世吨,增加一列復(fù)選框或者一列按鈕啥的澡刹,這是就需要用到$compile了。

    $compile耘婚,在Angular中即“編譯”服務(wù)罢浇,它涉及到Angular應(yīng)用的“編譯”和“鏈接”兩個(gè)階段,根據(jù)從DOM樹(shù)遍歷Angular的根節(jié)點(diǎn)(ng-app)和已構(gòu)造完畢的 \$rootScope對(duì)象边篮,依次解析根節(jié)點(diǎn)后代己莺,根據(jù)多種條件查找指令奏甫,并完成每個(gè)指令相關(guān)的操作(如指令的作用域,控制器綁定以及transclude等)凌受,最終返回每個(gè)指令的鏈接函數(shù)阵子,并將所有指令的鏈接函數(shù)合成為一個(gè)處理后的鏈接函數(shù),返回給Angluar的bootstrap模塊胜蛉,最終啟動(dòng)整個(gè)應(yīng)用程序挠进。

    先解說(shuō)下angular中頁(yè)面處理

    ng對(duì)頁(yè)面的處理過(guò)程:

    瀏覽器把HTML字符串解析成DOM結(jié)構(gòu)

    ng把DOM結(jié)構(gòu)給$compile,返回一個(gè)link函數(shù)

    傳入具體的scope調(diào)用這個(gè)link函數(shù)

    得到處理后的DOM誊册,這個(gè)DOM處理了指令领突,連接了數(shù)

    $compile是個(gè)編譯服務(wù)。編譯服務(wù)主要是為指令編譯DOM元素案怯。

    編譯一段HTML字符串或者DOM的模板君旦,產(chǎn)生一個(gè)將scope和模板連接到一起的函數(shù)。

    $compile用法:

    $compile(element,transclude,maxPriority);

    element:將要被編譯和插入模板的元素或者HTML字符串

    transclude:指令內(nèi)有效的函數(shù)嘲碱。Function(angular.Scope,cloneAttachFn=)

    maxPriority:只有在指令比給定的優(yōu)先級(jí)低時(shí)應(yīng)用金砍。只影響根元素,不影響子元素

    .controller('MyController', function ($scope, $compile) {

    ? ? ? ? ? ? ? ? // 創(chuàng)建編譯函數(shù)

    ? ? ? ? ? ? ? ? var compileFn = $compile('

    {{appCtrl.msg}}

    ');

    ? ? ? ? ? ? ? ? // 傳入scope麦锯,得到編譯好的dom對(duì)象(已封裝為jqlite對(duì)象)

    ? ? ? ? ? ? ? ? // 也可以用$scope.$new()創(chuàng)建繼承的作用域

    ? ? ? ? ? ? ? ? var $dom = compileFn($scope);

    ? ? ? ? ? ? ? ? // 添加到文檔中

    ? ? ? ? ? ? ? ? $dom.appendTo('body');

    ? ? ? ? ? ? })

    通過(guò)$compile服務(wù)可以編譯html字符串或dom對(duì)象或jqLite對(duì)象恕稠,然后得到一個(gè)編譯函數(shù),再傳入$scope扶欣,就會(huì)在當(dāng)前作用域進(jìn)行編譯鹅巍,返回編譯好的jqLite對(duì)象,這時(shí)就可以直接添加到文檔中了(也可以先添加到文檔再編譯)料祠。

    編譯的實(shí)質(zhì)其實(shí)就是對(duì)dom對(duì)象解析骆捧,使dom對(duì)象與scope進(jìn)行耦合,通過(guò)綁定可以實(shí)現(xiàn)數(shù)據(jù)的更新术陶,像Vue其實(shí)也是一樣的過(guò)程凑懂。

    $compile解說(shuō)推薦看《Angular中$compile源碼分析

    這篇是對(duì)angularJS的一些疑點(diǎn)回顧煤痕,文章的問(wèn)題大多是從網(wǎng)上搜集整理而來(lái)梧宫,如有不妥之處或不遠(yuǎn)被引用,請(qǐng)通知本人修改摆碉,謝謝塘匣!

    首發(fā)于周陸軍個(gè)人網(wǎng)站,轉(zhuǎn)載注明來(lái)源:《再談angularJS數(shù)據(jù)綁定機(jī)制及背后原理—angularJS常見(jiàn)問(wèn)題總結(jié)

    參考文章:

    溫故而知新-AngularJS 1.x 小記 (angularJS各個(gè)模塊系統(tǒng)概述)

    關(guān)于 AngularJS 的數(shù)據(jù)綁定黃騰飛的個(gè)人網(wǎng)站

    AngularJS 臟檢查深入分析

    理解Angular中的$apply()以及$digest()(翻譯:原文地址

    MVVM的簡(jiǎn)單實(shí)現(xiàn)-臟檢測(cè)

    Angular系列(徐飛博客:由淺入深地闡釋了angularJS)

    Angular 1 深度解析:臟數(shù)據(jù)檢查與 angular 性能優(yōu)化

    用$scope還是用controller as

    Controller As與$scope的區(qū)別($scope篇)

    《用AngularJS開(kāi)發(fā)下一代Web應(yīng)用》讀書(shū)筆記②:AngularJS應(yīng)用骨架

    AngularJs $compile編譯服務(wù)與指令

    玩轉(zhuǎn)Angular1(14)--使用$compile編譯指令

    Angular中$compile源碼分析

    angularjs使用$compile編譯模板后如何獲取編譯后的模板內(nèi)容并將其轉(zhuǎn)成字符串

    ?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
    • 序言:七十年代末巷帝,一起剝皮案震驚了整個(gè)濱河市忌卤,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌楞泼,老刑警劉巖驰徊,帶你破解...
      沈念sama閱讀 210,914評(píng)論 6 490
    • 序言:濱河連續(xù)發(fā)生了三起死亡事件笤闯,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡棍厂,警方通過(guò)查閱死者的電腦和手機(jī)颗味,發(fā)現(xiàn)死者居然都...
      沈念sama閱讀 89,935評(píng)論 2 383
    • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)牺弹,“玉大人浦马,你說(shuō)我怎么就攤上這事≌牌” “怎么了晶默?”我有些...
      開(kāi)封第一講書(shū)人閱讀 156,531評(píng)論 0 345
    • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)航攒。 經(jīng)常有香客問(wèn)我磺陡,道長(zhǎng),這世上最難降的妖魔是什么漠畜? 我笑而不...
      開(kāi)封第一講書(shū)人閱讀 56,309評(píng)論 1 282
    • 正文 為了忘掉前任仅政,我火速辦了婚禮,結(jié)果婚禮上盆驹,老公的妹妹穿的比我還像新娘圆丹。我一直安慰自己,他們只是感情好躯喇,可當(dāng)我...
      茶點(diǎn)故事閱讀 65,381評(píng)論 5 384
    • 文/花漫 我一把揭開(kāi)白布辫封。 她就那樣靜靜地躺著,像睡著了一般廉丽。 火紅的嫁衣襯著肌膚如雪倦微。 梳的紋絲不亂的頭發(fā)上,一...
      開(kāi)封第一講書(shū)人閱讀 49,730評(píng)論 1 289
    • 那天正压,我揣著相機(jī)與錄音欣福,去河邊找鬼。 笑死焦履,一個(gè)胖子當(dāng)著我的面吹牛拓劝,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播嘉裤,決...
      沈念sama閱讀 38,882評(píng)論 3 404
    • 文/蒼蘭香墨 我猛地睜開(kāi)眼郑临,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了屑宠?” 一聲冷哼從身側(cè)響起厢洞,我...
      開(kāi)封第一講書(shū)人閱讀 37,643評(píng)論 0 266
    • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后躺翻,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體丧叽,經(jīng)...
      沈念sama閱讀 44,095評(píng)論 1 303
    • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
      茶點(diǎn)故事閱讀 36,448評(píng)論 2 325
    • 正文 我和宋清朗相戀三年公你,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了蠢正。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
      茶點(diǎn)故事閱讀 38,566評(píng)論 1 339
    • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡省店,死狀恐怖嚣崭,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情懦傍,我是刑警寧澤雹舀,帶...
      沈念sama閱讀 34,253評(píng)論 4 328
    • 正文 年R本政府宣布,位于F島的核電站粗俱,受9級(jí)特大地震影響说榆,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜寸认,卻給世界環(huán)境...
      茶點(diǎn)故事閱讀 39,829評(píng)論 3 312
    • 文/蒙蒙 一签财、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧偏塞,春花似錦唱蒸、人聲如沸。這莊子的主人今日做“春日...
      開(kāi)封第一講書(shū)人閱讀 30,715評(píng)論 0 21
    • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至古今,卻和暖如春屁魏,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背捉腥。 一陣腳步聲響...
      開(kāi)封第一講書(shū)人閱讀 31,945評(píng)論 1 264
    • 我被黑心中介騙來(lái)泰國(guó)打工氓拼, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人抵碟。 一個(gè)月前我還...
      沈念sama閱讀 46,248評(píng)論 2 360
    • 正文 我出身青樓桃漾,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親立磁。 傳聞我的和親對(duì)象是個(gè)殘疾皇子呈队,可洞房花燭夜當(dāng)晚...
      茶點(diǎn)故事閱讀 43,440評(píng)論 2 348

    推薦閱讀更多精彩內(nèi)容

    • Angular面試題 一剥槐、ng-show/ng-hide與ng-if的區(qū)別唱歧? 第一點(diǎn)區(qū)別是,ng-if在后面表達(dá)式...
      w_zhuan閱讀 5,519評(píng)論 0 26
    • 1、angularjs的幾大特性是什么颅崩? 雙向數(shù)據(jù)綁定几于、依賴注入、模板沿后、指令沿彭、MVC/MVVM 2、列舉幾種常見(jiàn)的...
      2e9a10d418ab閱讀 1,261評(píng)論 0 10
    • 這篇博文主要是寫(xiě)給新手的,是給那些剛剛開(kāi)始接觸Angular漆弄,并且想了解數(shù)據(jù)幫定是如何工作的人睦裳。如果你已經(jīng)對(duì)Ang...
      iqing2012閱讀 336評(píng)論 0 3
    • 1.類(lèi)庫(kù)( 提供類(lèi)方法 ) 和框架 類(lèi)庫(kù)提供一系列的函數(shù)和方法的合集,能夠加快你寫(xiě)代碼的速度撼唾。但是主導(dǎo)邏輯的還是自...
      w_zhuan閱讀 1,786評(píng)論 0 8
    • Heven 從5倒谷、6月堅(jiān)持寫(xiě)作兩月余蛛蒙,中途七七八八暫停寫(xiě)作,到今天為止渤愁,已經(jīng)有將近2月沒(méi)有寫(xiě)東西了牵祟。習(xí)慣的養(yǎng)成真的...
      長(zhǎng)安筆客閱讀 617評(píng)論 9 10