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前端框架類型
共同特性:
· 選擇器(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的核心概念
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指令來指定引用所需要的模塊。
使用模塊帶來的好處: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)用的組件樹看起來是這樣的:
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模板
Dependency Injection(依賴注入):
一個(gè)對象通常有三種方式可以獲得對其依賴的控制權(quán)蚌父,分別是在內(nèi)部創(chuàng)建依賴;通過全局變量進(jìn)行引用烟具;通過參數(shù)進(jìn)行傳遞。我們所說的依賴注入就是通過第三種方式實(shí)現(xiàn)的奠蹬。
DI的代碼邏輯:需要什么對象朝聋,聲明一下即可,由外界的框架創(chuàng)建這些對象囤躁,然后根據(jù)每個(gè)形參的名稱來查找依賴對象并且注入進(jìn)來冀痕。若聲明形參名稱有錯誤,則無法提供該對象狸演。
如果沒有明確的聲明言蛇,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中最重要的功能之一。
所謂的雙向綁定讲衫,無非是從界面的操作能實(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中的指令