前端開發(fā)框架之AngularJS篇

1拓劝、 前端视卢,是一種GUI軟件

在一個(gè)Web系統(tǒng)中踱卵,用戶通過瀏覽器上網(wǎng),輸入U(xiǎn)RL的那一刻起据过,就意味著通過HTTP協(xié)議發(fā)送一個(gè)遠(yuǎn)程請求惋砂,服務(wù)端會將一個(gè)URL請求映射到一個(gè)具體的URL,然后將關(guān)聯(lián)的資源分別返回給瀏覽器端绳锅,瀏覽器拿到了這些資源之后班利,負(fù)責(zé)解釋、執(zhí)行并呈現(xiàn)(渲染)榨呆。

從本質(zhì)上講罗标,所有Web應(yīng)用都是一種運(yùn)行在網(wǎng)頁瀏覽器中的軟件,這些軟件的圖形用戶界面(Graphical User Interface积蜻,簡稱GUI)即為前端闯割。【1】

2竿拆、 傳統(tǒng)前端文件

HTML(現(xiàn)在常用HTML5)宙拉,標(biāo)記語言,負(fù)責(zé)呈現(xiàn)網(wǎng)頁的結(jié)構(gòu)以及內(nèi)容丙笋。打個(gè)比方谢澈,一棟房子,它有多少層御板,每一層里面锥忿,有幾間房間,臥室怠肋、廚房敬鬓、衛(wèi)生間的分布,玻璃窗戶的分布,房子的結(jié)構(gòu)和房子的內(nèi)容【2】钉答〈∩郑可以通過靜態(tài)HTML標(biāo)記呈現(xiàn),也可以通過JavaScript編程動態(tài)展現(xiàn)数尿。對于JS來說仑性,一個(gè)完整的HTML文檔就是一棵樹,稱之為DOM(DocumentObject Model右蹦,文檔對象模型)虏缸,對DOM的操作稱為DOM操作。

JQuery的DOM操作示例: var p_txt =$("p").attr("title");

CSS(常用CSS3)嫩实,樣式語言,負(fù)責(zé)網(wǎng)頁內(nèi)容的顯示樣式窥岩。還是上面的例子甲献,一個(gè)房子里面某個(gè)房間的墻的顏色,窗戶的風(fēng)格等等颂翼。

JavaScript晃洒,腳本語言。腳本實(shí)際上就是為整個(gè)HTML Document增加了動態(tài)交互的能力朦乏。不同的瀏覽器有著不同的JavaScript實(shí)現(xiàn)球及,所以實(shí)現(xiàn)JavaScript跨瀏覽器兼容成為了后來評論一個(gè)JS框架是否實(shí)用的一個(gè)基本的標(biāo)準(zhǔn)。

3呻疹、 JS框架

3.1前端框架類型
圖1 常用的一些前端框架

共同特性:

· 選擇器(Selector)

· DOM 遍歷

· DOM 操作

· 實(shí)用(Utility)函數(shù)

· 事件處理

· Ajax

3.2 JS框架定義

JavaScript框架或庫是一組能輕松生成跨瀏覽器兼容的JavaScript 代碼的工具和函數(shù),每一個(gè)庫都在眾多流行的Web 瀏覽器的現(xiàn)代版本上進(jìn)行了可靠的測試.

3.3 為什么要用JS框架吃引?

JavaScript框架或庫是一組能輕松生成跨瀏覽器兼容的 JavaScript 代碼;另一個(gè)比較有說服力的理由是標(biāo)準(zhǔn)化的跨瀏覽器 Ajax 請求(Ajax 請求是一個(gè)異步 HTTP 請求刽锤,通常發(fā)送給服務(wù)器端腳本镊尺,后者返回 XML、JSON并思、HTML 或普通文本格式的響應(yīng))庐氮。

4、 AngularJS

AngularJS由 Google 的員工 MiskoHevery 從 2009 年開始著手開發(fā)宋彼,2012年發(fā)布版本1.0弄砍。該項(xiàng)目目前已由 Google 正式收購,有一個(gè)全職的開發(fā)團(tuán)隊(duì)繼續(xù)開發(fā)和維護(hù)這個(gè)庫输涕。并且在2014年秋天發(fā)布了2.0版本音婶,2016年9月發(fā)布了2.0最終版。

4.1 AngularJS的核心概念
圖2 AngularJS的七個(gè)核心概念【3】
Modules(模塊):

在前端開發(fā)過程中莱坎,通常的做法都是將處理業(yè)務(wù)邏輯的代碼寫在一個(gè)單獨(dú)的JS文件中桃熄,然后在HTML頁面中引入該文件。這樣會帶來新的問題,我們的控制器全都定義在全局的命名空間中瞳收。假設(shè)我們有一個(gè)公共的JS文件碉京,在登錄頁面和密碼修改頁面都引入這個(gè)JS,A開發(fā)人員和B開發(fā)人員碰巧對控制器的命名都是UserController螟深,這樣就會導(dǎo)致命名沖突(全局變量污染)【4】谐宙。而且我們在新增一個(gè)控制器的時(shí)候總是要擔(dān)心是不是已經(jīng)有了一個(gè)同名的控制器,代碼的擴(kuò)展性變得很差界弧。

AngularJS允許我們使用angular.module()方法來聲明模塊凡蜻,這個(gè)方法接受兩個(gè)參數(shù),第一個(gè)是我們定義的模塊名稱垢箕,第二個(gè)是依賴列表划栓,也就是可以被注入到模塊中的對象列表。

angular.module(‘myApp’,[]);

對于上述例子条获,我們可以將不同的控制器封裝在不同的模塊中忠荞,然后在對應(yīng)的HTML文檔中用ng-app指令來指定引用所需要的模塊。

圖3 模塊的引用
圖4 模塊的定義

使用模塊帶來的好處:1帅掘、保持全局命名空間的清潔委煤;2、易于在不同的應(yīng)用間復(fù)用代碼修档;3碧绞、使應(yīng)用能夠以任意順序加載代碼的各個(gè)部分。

Components(組件):

組件是Angular2.0中最基本的一個(gè)概念吱窝。一個(gè)組件包含一個(gè)視圖即我們用來展示信息或者完成用戶交互的頁面讥邻。 技術(shù)上來講, 一個(gè)組件就是一個(gè)控制模板視圖的類院峡, 在開發(fā)應(yīng)用中會寫很多組件计维。

一個(gè)應(yīng)用中總是存在一個(gè)根(主)組件,根組件中包含了其他組件撕予。簡而言之鲫惶,每一個(gè)Angular 2應(yīng)用都有一棵對應(yīng)的組件樹。我們應(yīng)用的組件樹看起來是這樣的:

圖5 組件樹【5】
Template(模板):

AngularJS的主旨即快速創(chuàng)建單頁面應(yīng)用实抡,所謂單頁面就是說真正的頁面只有一個(gè)欠母,其中變化的只是模板和數(shù)據(jù)。在AngularJS中吆寨,一個(gè)模板就是一個(gè)HTML文件赏淌,HTML模板將會被瀏覽器解析到DOM中,DOM然后成為AngularJS編譯器的輸入啄清,AngularJS將會遍歷DOM模板來生成一些指令六水。

ng-If是個(gè)對于模板很重要的指令,它是基本的條件表達(dá),滿足條件時(shí)則存在掷贾,不滿足則不存在睛榄。通過它可以輕松的讓模板基于數(shù)據(jù)呈現(xiàn)不同結(jié)構(gòu)。

ng-Repeat則是另一重要指令想帅,能循環(huán)創(chuàng)建DOM场靴。可以說只要數(shù)據(jù)中有數(shù)組等結(jié)構(gòu)港准,這一指令就必不可少

ng-Class是樣式層面上的主要指令旨剥,它的值可以是存放class名的變量,也可以是帶有條件的對象

這些基本的指令構(gòu)成了一套很有效的模板邏輯浅缸,我們可以消除掉各種HTML的重復(fù)性代碼轨帜,還能在單個(gè)模板中呈現(xiàn)出無數(shù)的形式。

以下為一個(gè)例子衩椒,ng-repeat指令來循環(huán)圖片數(shù)組并且加入img模板

圖6 模板示例
Dependency Injection(依賴注入):

一個(gè)對象通常有三種方式可以獲得對其依賴的控制權(quán)蚌父,分別是在內(nèi)部創(chuàng)建依賴;通過全局變量進(jìn)行引用烟具;通過參數(shù)進(jìn)行傳遞。我們所說的依賴注入就是通過第三種方式實(shí)現(xiàn)的奠蹬。

DI的代碼邏輯:需要什么對象朝聋,聲明一下即可,由外界的框架創(chuàng)建這些對象囤躁,然后根據(jù)每個(gè)形參的名稱來查找依賴對象并且注入進(jìn)來冀痕。若聲明形參名稱有錯誤,則無法提供該對象狸演。

圖7 依賴注入示例

如果沒有明確的聲明言蛇,AngularJS會假定參數(shù)名稱就是依賴的名稱。因此宵距,它會在內(nèi)部調(diào)用函數(shù)對象的ToString()方法腊尚,分析并提取出函數(shù)參數(shù)列表,然后通過$injector(AngularJS中的一種服務(wù))將這些參數(shù)注入進(jìn)對象實(shí)例【6】满哪。

Services(服務(wù)):

在 AngularJS 中婿斥,服務(wù)是一個(gè)函數(shù)或?qū)ο螅稍贏ngularJS 應(yīng)用中使用哨鸭。AngularJS 內(nèi)建了一共30 多個(gè)服務(wù)民宿。

  • 首先是一個(gè)單例,即無論這個(gè)服務(wù)被注入到任何地方像鸡,對象始終只有一個(gè)實(shí)例活鹰。
  • 其次服務(wù)被定義在一個(gè)模塊中,所以其使用范圍是可以被我們管理的,避免全局變量污染志群。

AngularJS中幾種服務(wù)示例:

$http:用于處理 XMLHttpRequest

$location:提供當(dāng)前URL的信息

$routeProvider:配置路由

$log:日志服務(wù)

定義服務(wù)有三種方式:使用系統(tǒng)內(nèi)置的$provide服務(wù)着绷;使用Module的factory方法;使用Module的service方法【7】赖舟。

//使用factory方法

app.factory('remoteData',function(){

   var data = {name:'n',value:'v'};

   return data;

});
//使用service方法

app.service('remoteData',function(){

   this.name = 'n';

   this.value = 'v';

});
Data Binding(數(shù)據(jù)綁定):

在傳統(tǒng)的web框架中蓬戚,控制器將多個(gè)模型中的數(shù)據(jù)和模板組合在一起形成視圖,并將其提供給用戶宾抓,如果沒有任何自定義的JavaScript組件子漩,這樣的視圖只會體現(xiàn)出它渲染時(shí)模型暴露出的數(shù)據(jù)。AngularJS創(chuàng)建了一個(gè)實(shí)時(shí)模板來代替視圖石洗,任何一個(gè)獨(dú)立視圖組件中的值都是動態(tài)替換的幢泼,這是AngularJS中最重要的功能之一。

圖8 數(shù)據(jù)綁定
圖9 數(shù)據(jù)綁定演示

所謂的雙向綁定讲衫,無非是從界面的操作能實(shí)時(shí)反映到數(shù)據(jù)缕棵,數(shù)據(jù)的變更能實(shí)時(shí)展現(xiàn)到界面。

<div ng-controller="CounterCtrl">

    <span ng-bind="counter"></span>

    <button ng-click="counter=counter+1">increase</button>

</div>

function CounterCtrl($scope) {

    $scope.counter = 1;

}

The ng-Bind attribute tells Angular to replace the text content of the specified HTML element with the value of a given expression, and to updatethe text content when the value of that expression changes.

AngularJS選擇了dirty check涉兽。簡單來說就是給每個(gè)需要綁定的元素加個(gè)watcher招驴,緩存下OldValue,然后定時(shí)遍歷所有的watcher枷畏,比較NewValue和OldValue别厘,如果變化了做更新操作。

一拥诡、瀏覽器事件循環(huán)和AngularJS拓展

我們的瀏覽器一直在等待事件触趴,比如用戶交互。假如你點(diǎn)擊一個(gè)按鈕或者在輸入框里輸入東西渴肉,事件的回調(diào)函數(shù)就會在javascript解釋器里執(zhí)行冗懦,然后你就可以做任何DOM操作,等回調(diào)函數(shù)執(zhí)行完畢時(shí)仇祭,瀏覽器就會相應(yīng)地對DOM做出變化披蕉。 Angular拓展了這個(gè)事件循環(huán),生成一個(gè)angular context的執(zhí)行環(huán)境乌奇。

二嚣艇、watch隊(duì)列(watch list)

每次你綁定一些東西到你的UI上時(shí)你就會往$watch隊(duì)列里插入一條$watch。$watch就是那個(gè)可以檢測它監(jiān)視的model里有變化的東西华弓。當(dāng)我們的模版加載完畢時(shí)食零,也就是在linking階段(Angular分為compile階段和linking階段),Angular解釋器會尋找每個(gè)directive寂屏,然后生成每個(gè)需要的$watch贰谣。

三娜搂、$digest循環(huán)

當(dāng)瀏覽器接收到可以被angular context處理的事件時(shí),digest循環(huán)就會觸發(fā)吱抚,digest將會遍歷我們的watch隊(duì)列百宇,然后詢問它是否有屬性和值的變化,直到$watch隊(duì)列都檢查過秘豹。這就是所謂的dirty-checking携御。當(dāng)所有的$watch都檢查完了,如果有至少一個(gè)更新過既绕,這個(gè)循環(huán)就會再次觸發(fā)啄刹,直到所有的$watch都沒有變化。這樣就能夠保證每個(gè)model都已經(jīng)不會再變化凄贩,如果循環(huán)超過10次的話誓军,它將會拋出一個(gè)異常,防止無限循環(huán)疲扎。 當(dāng)$digest循環(huán)結(jié)束時(shí)昵时,DOM相應(yīng)地變化【8】。

Directive(指令)

指令本質(zhì)上就是AngularJS擴(kuò)展具有自定義功能的HTML元素的途徑椒丧,是一個(gè)封裝的組件壹甥,傳入?yún)?shù)也通過在html標(biāo)簽中設(shè)置屬性來實(shí)現(xiàn),而不需要去修改JS代碼壶熏。就像一個(gè)函數(shù)一樣句柠,可以到處的調(diào)用(復(fù)用),并且設(shè)置不同的屬性(參數(shù))來實(shí)現(xiàn)不同的功能久橙。

在HTML中要用內(nèi)置指令ng-app標(biāo)記出應(yīng)用的根節(jié)點(diǎn)俄占,這個(gè)指令需要以屬性的形式來使用管怠,因此可以將它寫到任何位置淆衷,但是寫到<html>的開始標(biāo)簽上是最常規(guī)的做法。所有內(nèi)置指令的命名空間都使用ng作為前綴渤弛,比如之前所說的ng-repeat祝拯、ng-app、ng-If等她肯。因此我們在自定義指令命名時(shí)佳头,為了防止命名空間沖突,不要在自定義指令前加ng前綴晴氨。

自定義的指令一般有四種表現(xiàn)形式:

1康嘉、作為一個(gè)新的HTML元素來使用。

<hello></hello>或者<hello/>

2籽前、作為一個(gè)元素的屬性來使用

<div hello></div>

3亭珍、作為一個(gè)元素的類來使用

<div class="hello"></div>

4敷钾、作為注釋來使用

<!--directive: hello-->

下面是定義一個(gè)最簡單指令的示例代碼:

var app =angular.module('app',[])

app.directive('hello',function(){
    return {
       restrict:'AECM',
       template:'<button>clickme</button>'
    }
})

1、restrict[string]這個(gè)屬性肄梨,主要是用來規(guī)定指令在HTML代碼中可以使用什么表現(xiàn)形式阻荒。A代表屬性、E代表元素众羡、C代表類侨赡、M代表注釋。

2粱侣、template[string or function]這個(gè)屬性羊壹,規(guī)定了指令被Angular編譯和鏈接(link)后生成的HTML標(biāo)記,這個(gè)屬性可以簡單到只有一個(gè)HTML文本在里面甜害,也可以特別復(fù)雜舶掖,當(dāng)該屬性的值為function的時(shí)候,那么該方法返回的就是代表模板的字符串尔店。

在定義指令的時(shí)候眨攘,除了以上最基礎(chǔ)的兩個(gè)屬性外,我們還會使用很多其它的屬性嚣州,

1鲫售、priority[number]屬性,這個(gè)屬性是來規(guī)定自定義的指令的優(yōu)先級的该肴,當(dāng)一個(gè)DOM元素上面有一個(gè)以上的指令的時(shí)候情竹,就需要去比較指令的優(yōu)先級了,優(yōu)先級高的指令先執(zhí)行匀哄。

2秦效、terminal[boolean]屬性,該參數(shù)用來定義是否停止當(dāng)前元素上比本指令優(yōu)先級低的指令涎嚼,如果值為true阱州,就是正常情況,按照優(yōu)先級高低的順序來執(zhí)行法梯,如果設(shè)置為false苔货,就不會執(zhí)行當(dāng)前元素上比本指令優(yōu)先級低的指令【9】。

參考資料

[1]https://github.com/fouber/blog/issues/10 百度工程師張?jiān)讫埱岸斯こ?基礎(chǔ)篇

[2]http://www.cnblogs.com/fecktty2013/p/4800645.html周信達(dá) 小菜的前端編程散談

[3]https://gf-rd.gitbooks.io/angular-2-step-by-step/content/chapters/1.2.htmlAngularJS的七個(gè)核心概念圖片來源

[4]http://blog.csdn.net/rongbo_j/article/details/45438181AngularJS輕松入門(四)模塊化

[5]https://segmentfault.com/a/1190000004329594#articleHeader4AngularJS核心概念之組件樹 圖片來源

[6]http://www.cnblogs.com/tangshiwei/p/5496268.htmlAngularJS學(xué)習(xí)筆記之依賴注入

[7]http://www.cnblogs.com/lijin1185374093/p/5938443.html走進(jìn)AngularJS----服務(wù)

[8]http://angular-tips.com/blog/2013/08/watch-how-the-apply-runs-a-digest/ AngularJS Tips

[9]http://www.cnblogs.com/ww-ervin-72/p/5296788.htmlAngularJS中的指令

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末立哑,一起剝皮案震驚了整個(gè)濱河市夜惭,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌铛绰,老刑警劉巖诈茧,帶你破解...
    沈念sama閱讀 206,602評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異捂掰,居然都是意外死亡敢会,警方通過查閱死者的電腦和手機(jī)镊叁,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,442評論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來走触,“玉大人晦譬,你說我怎么就攤上這事』ス悖” “怎么了敛腌?”我有些...
    開封第一講書人閱讀 152,878評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長惫皱。 經(jīng)常有香客問我像樊,道長,這世上最難降的妖魔是什么旅敷? 我笑而不...
    開封第一講書人閱讀 55,306評論 1 279
  • 正文 為了忘掉前任生棍,我火速辦了婚禮,結(jié)果婚禮上媳谁,老公的妹妹穿的比我還像新娘涂滴。我一直安慰自己,他們只是感情好晴音,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,330評論 5 373
  • 文/花漫 我一把揭開白布柔纵。 她就那樣靜靜地躺著,像睡著了一般锤躁。 火紅的嫁衣襯著肌膚如雪搁料。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,071評論 1 285
  • 那天系羞,我揣著相機(jī)與錄音郭计,去河邊找鬼。 笑死椒振,一個(gè)胖子當(dāng)著我的面吹牛昭伸,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播杠人,決...
    沈念sama閱讀 38,382評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼勋乾,長吁一口氣:“原來是場噩夢啊……” “哼宋下!你這毒婦竟也來了嗡善?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,006評論 0 259
  • 序言:老撾萬榮一對情侶失蹤学歧,失蹤者是張志新(化名)和其女友劉穎罩引,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體枝笨,經(jīng)...
    沈念sama閱讀 43,512評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡袁铐,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,965評論 2 325
  • 正文 我和宋清朗相戀三年揭蜒,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片剔桨。...
    茶點(diǎn)故事閱讀 38,094評論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡屉更,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出洒缀,到底是詐尸還是另有隱情瑰谜,我是刑警寧澤,帶...
    沈念sama閱讀 33,732評論 4 323
  • 正文 年R本政府宣布树绩,位于F島的核電站萨脑,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏饺饭。R本人自食惡果不足惜渤早,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,283評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望瘫俊。 院中可真熱鬧鹊杖,春花似錦、人聲如沸扛芽。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,286評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽胸哥。三九已至涯竟,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間空厌,已是汗流浹背庐船。 一陣腳步聲響...
    開封第一講書人閱讀 31,512評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留嘲更,地道東北人筐钟。 一個(gè)月前我還...
    沈念sama閱讀 45,536評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像赋朦,于是被迫代替她去往敵國和親篓冲。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,828評論 2 345

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