AngularJs html compiler詳解及示例代碼
原文再續(xù),書(shū)接上回。。。依舊參考http://code.angularjs.org/1.0.2/docs/guide/compiler
一、總括
Angular的HTML compiler允許開(kāi)發(fā)者自定義新的HTML語(yǔ)法。compiler允許我們對(duì)任意HTML元素或?qū)傩?,甚至是新的HTML標(biāo)簽、屬性(如<beautiful girl=”cf”></beautiful >)附加行為。Angular將這些附加行為稱為directives。
HTML有很多專門(mén)格式化靜態(tài)文檔的預(yù)定義HTML樣式結(jié)構(gòu)(可以告訴瀏覽器如何顯示標(biāo)記的內(nèi)容)。假設(shè)某東東需要被居中,而我們不需要教瀏覽器如何去做(此處省略N字)。我們只需要簡(jiǎn)單地對(duì)需要居中的標(biāo)簽加入align=”center”即可。這就是聲明式語(yǔ)言(declarative language)的牛X之處。
但是聲明式語(yǔ)言也有它的局限性,即你不能告訴瀏覽器如何處理在預(yù)定義范圍外的語(yǔ)法。例如,我們不能很簡(jiǎn)單地告訴瀏覽器如何讓文本在瀏覽器的1/3處對(duì)齊。所以,我們正需要一個(gè)讓瀏覽器與時(shí)俱進(jìn),學(xué)學(xué)新語(yǔ)法的途徑。
Angular預(yù)先綁定了一些對(duì)構(gòu)建應(yīng)用有幫助的directives。我們也可以自己創(chuàng)建屬于自己應(yīng)用的獨(dú)特的directives。這些directive擴(kuò)展將成為我們自己的應(yīng)用的“特定領(lǐng)域語(yǔ)言”(Domain Specific Language)。
這些編譯將僅僅發(fā)生在瀏覽器端,無(wú)須服務(wù)端或者預(yù)編譯步驟。
二、Compiler
Compiler作為Angular的一個(gè)服務(wù)(Service),負(fù)責(zé)遍歷DOM結(jié)構(gòu),尋找屬性。編譯過(guò)程分成兩個(gè)階段:
1. 編譯(Compile):遍歷DOM節(jié)點(diǎn)樹(shù),收集所有directives。返回結(jié)果是一個(gè)鏈接函數(shù)(linking function)。
2. 鏈接(Link):將directives綁定到一個(gè)作用域(scope)中,創(chuàng)建一個(gè)實(shí)況視圖(live view)。在scope中的任何改變,將會(huì)在視圖中得到體現(xiàn)(更新視圖);任何用戶對(duì)模版的活動(dòng)(改變),將會(huì)體現(xiàn)在scope model中(雙向綁定)。這使得scope model能夠反映正確的值。
一些directives,諸如ng-repeat,會(huì)為每一個(gè)在集合(collection)中的元素復(fù)制一次特定的元素(組合)。編譯和鏈接兩個(gè)階段,使性能得以提升。因?yàn)榭寺〕鰜?lái)的模版(template)只需要編譯一次,然后為每一個(gè)集合中的元素進(jìn)行一次鏈接(類似模版緩存)。
三、Directive
Directive是一個(gè)行為,在編譯過(guò)程中遇到特定的HTML結(jié)構(gòu)時(shí),它會(huì)被觸發(fā)。Directives可以放置在元素的name、attribute、class甚至注釋中。以下是幾種引用ng-bind(一個(gè)內(nèi)置directive)的方法:
<span ng-bind="exp"></span> <span class="ng-bind: exp;"></span> <ng-bind></ng-bind> <!-- directive: ng-bind exp -->
Directive只是一個(gè)當(dāng)編譯器在DOM中遇到時(shí)會(huì)執(zhí)行的一個(gè)函數(shù)(function)。directive API文檔中有詳細(xì)講解如何創(chuàng)建一個(gè)directive。
下面是一個(gè)樣例,可以讓一個(gè)元素跟你的鼠標(biāo)玩躲貓貓……
<!DOCTYPE html>
<html lang="zh-cn" ng-app="HideAnkSeek">
<head>
<meta charset="UTF-8">
<title>躲貓貓</title>
<style type="text/css">
.ng-cloak {
display: none;
}
</style>
</head>
<body>
<span class="ng-cloak" wildcat>一碰我就跑~~來(lái)點(diǎn)我啊~~</span>
<script src="../angular-1.0.1.js" type="text/javascript"></script>
<script type="text/javascript">
angular.module("HideAnkSeek", []).directive("wildcat", function ($document) {
var maxLeft = 400,maxTop = 300;
var msg = ["我閃~~", "抓我呀~~~", "雅蠛蝶~~", "噢耶~~", "你真遜~!","就差那么一點(diǎn)點(diǎn)了!","繼續(xù)吧~~總有一天我會(huì)累的"];
return function (scope, element, attr) {
element.css({
"position":"absolute",
"border":"1px solid green"
});
element.bind("mouseenter", function (event) {
element.css({
"left":parseInt(Math.random() * 10000 % maxLeft) + "px",
"top":parseInt(Math.random() * 10000 % maxTop) + "px"
}).text(msg[parseInt(Math.random() * 10000 % msg.length)]);
}).bind("click",function (event) {
element.text("噢My Lady Gaga。。。被你逮到了。。。");
element.unbind("mouseenter");
});
};
});
</script>
</body>
</html>
在任意元素中添加“wildcat”這個(gè)屬性,將會(huì)使該元素?fù)碛行碌男袨?。就這樣,我們教會(huì)了瀏覽器如何處理會(huì)躲貓貓的元素(放心,你不是在某個(gè)房間,你不會(huì)掛的-_-!)。我們通過(guò)這一途徑擴(kuò)展了瀏覽器的“詞匯量”。對(duì)于任意一個(gè)熟悉HTML規(guī)則的人,這算是一個(gè)比較自然的方式。
現(xiàn)在已經(jīng)夜深了,明天繼續(xù)。。。廣告之后見(jiàn)
===================華麗的分割線=======================
四、理解視圖(View)
外面有許多模版系統(tǒng),它們通常都通過(guò)模版字符串與數(shù)據(jù)進(jìn)行連接,生成最終的HTML字符串,并將結(jié)果通過(guò)innerHTML屬性寫(xiě)入某元素里。

這意味著任何數(shù)據(jù)發(fā)生改變時(shí),都需要重新將數(shù)據(jù)、模版合并成字符串,然后當(dāng)作innerHTML寫(xiě)回對(duì)應(yīng)元素中。這里存在一些問(wèn)題:(這里直譯實(shí)在沒(méi)法懂..唯有YY)假設(shè)有這么一個(gè)場(chǎng)景,模版里包含輸入框。用戶對(duì)在輸入框進(jìn)行輸入,模版同步更新。普通模版通過(guò)innerHTML、字符串與數(shù)據(jù)連接的方式更新視圖,這樣會(huì)打斷用戶的輸入,體驗(yàn)不好。
Angular是與眾不同的。Angular編譯器(compiler)通過(guò)directives處理DOM,而不是通過(guò)處理字符串模版。處理結(jié)果是一個(gè)與scope model組合并生成實(shí)時(shí)模版的鏈接函數(shù)(linking function)。視圖與scope model的綁定對(duì)我們來(lái)說(shuō)是透明的。開(kāi)發(fā)者無(wú)須為更新視圖、model做任何動(dòng)作。而且,因?yàn)闆](méi)有使用innerHTML更新視圖模版,所以用戶輸入不會(huì)被打斷。此外,angular directives不僅可以綁定文本值,而且還可以是擁有行為的結(jié)構(gòu)(behavioral constructs)。

Angular的這個(gè)處理方式,產(chǎn)生了一個(gè)穩(wěn)定的DOM。這意味著在DOM元素的生命周期里,一直與某model的實(shí)例綁定著,這個(gè)關(guān)系不會(huì)發(fā)生改變。這也意味著代碼可以保持對(duì)某DOM對(duì)象的引用,對(duì)其注冊(cè)事件函數(shù),并且這個(gè)引用不會(huì)被模版數(shù)據(jù)合并所銷(xiāo)毀。
相關(guān)文章
AngularJs基于角色的前端訪問(wèn)控制的實(shí)現(xiàn)
本篇文章主要介紹了AngularJs實(shí)現(xiàn)基于角色的前端訪問(wèn)控制,可以適用于不同的角色,有需要的可以了解一下。2016-11-11
詳解Angular系列之變化檢測(cè)(Change Detection)
這篇文章主要介紹了詳解Angular系列之變化檢測(cè)(Change Detection),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-02-02
AngularJS實(shí)現(xiàn)的2048小游戲功能【附源碼下載】
這篇文章主要介紹了AngularJS實(shí)現(xiàn)的2048小游戲,可實(shí)現(xiàn)通過(guò)鍵盤(pán)W、S、A、D鍵控制上下左右移動(dòng)進(jìn)行游戲的功能,涉及AngularJS頁(yè)面元素動(dòng)態(tài)操作及數(shù)值運(yùn)算等相關(guān)操作技巧,并附帶源碼供讀者下載參考,需要的朋友可以參考下2018-01-01
AngularJs 最新驗(yàn)證手機(jī)號(hào)碼的實(shí)例,成功測(cè)試通過(guò)
下面小編就為大家分享一篇AngularJs 最新驗(yàn)證手機(jī)號(hào)碼的實(shí)例,成功測(cè)試通過(guò),具有很好的參考價(jià)值。希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2017-11-11
Ionic + Angular.js實(shí)現(xiàn)圖片輪播的方法示例
圖片輪播在我們?nèi)粘i_(kāi)發(fā)中是再熟悉不過(guò)的了,下面這篇文章主要給大家介紹了Ionic + Angular實(shí)現(xiàn)圖片輪播的方法,文中給出了詳細(xì)的示例代碼供大家參考學(xué)習(xí),需要的朋友們下面來(lái)一起看看吧。2017-05-05
Angularjs使用ng-repeat中$even和$odd屬性的注意事項(xiàng)
無(wú)可否認(rèn)angularjs的崛起成為前端很大的福利,最近接到項(xiàng)目,框架便選中了angularjs。angularjs最吸引人的地方就是數(shù)據(jù)的雙向綁定和指令了,這篇文章主要介紹了Angularjs中使用ng-repeat的$even和$odd屬性的注意事項(xiàng),需要的朋友可以參考下2016-12-12

