![angularjs權(quán)威教程譯者野_第1頁](http://file4.renrendoc.com/view/a0b5a7e19a04e5a8023a85d99f7141a3/a0b5a7e19a04e5a8023a85d99f7141a31.gif)
![angularjs權(quán)威教程譯者野_第2頁](http://file4.renrendoc.com/view/a0b5a7e19a04e5a8023a85d99f7141a3/a0b5a7e19a04e5a8023a85d99f7141a32.gif)
![angularjs權(quán)威教程譯者野_第3頁](http://file4.renrendoc.com/view/a0b5a7e19a04e5a8023a85d99f7141a3/a0b5a7e19a04e5a8023a85d99f7141a33.gif)
![angularjs權(quán)威教程譯者野_第4頁](http://file4.renrendoc.com/view/a0b5a7e19a04e5a8023a85d99f7141a3/a0b5a7e19a04e5a8023a85d99f7141a34.gif)
![angularjs權(quán)威教程譯者野_第5頁](http://file4.renrendoc.com/view/a0b5a7e19a04e5a8023a85d99f7141a3/a0b5a7e19a04e5a8023a85d99f7141a35.gif)
版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
1章初識AnguarJS2章數(shù)據(jù)綁定和第個AnguarJSWeb應(yīng)用HeoWord第3章模塊第4章作用域第5章控制器第6章表達式第7章過濾器第8章指令簡介第9章內(nèi)置指令第10章指令詳解優(yōu)先級(數(shù)值型transc11章AnguarJS第12 多重視圖和路$ocatonHTML5第13章依賴注入$njectornstantngM第14個服務(wù)servprovva15章同外界通信:XHR器設(shè)置$httpProv使用應(yīng)用$resource$resource使用Restanguar安裝使用16章XHR使用使用使用第17章promseAnguar中的prom如何創(chuàng)建個prom第18章安裝安裝調(diào)用簡單通知服務(wù)簡單服務(wù)安全令牌服務(wù)AWSJS+UserServAWSServ保存上傳到查詢 并創(chuàng)建個F包含F(xiàn)rebase和AnguarFreF$第19章測試Jasm定義個細則模擬測試個應(yīng)用建立我們的第個測試還要20
20.4對21
ngRepeatngVewngIncudengSwngCassngShow/ngHdeaddCremoveCcanceAnTweenMax/TweenL23章dgest循環(huán)和$app$watch$watchCoect$evaAsync$app第24章25章AnguarJSu-$urRouterProv創(chuàng)建個導(dǎo)航程序u-u-第26章$swpeAnguar中的Cordova第27章本地化anguar-trans教你的應(yīng)用種新語言anguar-第28章緩存$cacheFactory第29章安全性$scesEnab配置30章AnguarJS和IE瀏覽器AnguarJS中的hashbang使用grunt-htm-Prerender.<noscrpt>章構(gòu)建manPresentymanpete32章優(yōu)化Anguar應(yīng)用b33章調(diào)試nherAnguar安第34章下步grunt-anguar-tempLBower配置第35章總結(jié)Orgnaedton,enttedTheCompleteBookonAngularJSMachnes.Copyrght?2013byArLerner.SmpfedChnesetransatoncopyrght?2014byPosts& photocopyng,recordngorbyanynformatonstorageandretrevasystem,wthoutpermssonnwrtngfromW.W.Norton&,本書簡體中文版由ArLerner.人民郵電獨家。 者,不得以任何方式本書內(nèi)容。僅限于中民境內(nèi)(中國、特別行政區(qū)和地區(qū)除外)銷售。,在上這本請幫ArLerner在上宣傳這本書。推薦本書:.we 特別感謝可愛的Q,感謝你直以來的激勵,以及你在編輯方面的過人天賦。感謝我的共同創(chuàng)始人兼朋友NateMurray2年上半年,我所在的公司正在開發(fā) 個二次開發(fā)平臺,它的目標是從數(shù)據(jù)庫開始,能自由、方便地定制業(yè)務(wù)數(shù)據(jù)、規(guī)則、流程、服務(wù)還有展現(xiàn)層。在對展現(xiàn)層的實現(xiàn)部分,我思考了很久,對其中部分技術(shù)細節(jié)還是缺乏好的思路,于是把眼光轉(zhuǎn)到開源社區(qū),無意中發(fā)現(xiàn)了AnguarJS這樣個框架,詳細之后,我認為它在很大程度上滿足了我們的需求,繼而投入了不小的精力進行研究 開發(fā)者王宇鵬等進行了交流,獲得了很多有益的信息,與此同時,也跟Avaon的作者司徒正美有過些討論,對前端MV*有了更深入的認識。后來,團隊中的大漠窮秋翻譯的《用AnguarJS開發(fā)下代Web應(yīng)用》由電子工業(yè)。作為國內(nèi)第本關(guān)于AnguarJS的譯著,它帶動了學(xué)習(xí)和了解AnguarJS框架的浪潮,也因此與樸靈的《深入淺出Node.js》起,成為前端開發(fā)人員拓展思維和技能的兩本最受歡迎。在此期間,公司的李松峰老師發(fā)布了本書招募譯者的消息,我心里動就聯(lián)系了他。經(jīng)過溝通之后,我與另外兩名譯者,豌豆莢的@野和騰訊的@basecss,合作翻譯本書,每人負責(zé)1/3的內(nèi)容。第次正式翻譯,我很忐忑,翻譯過程中也遇到了些。此前我雖翻譯過些技術(shù)文章,其中篇恰好與AnguarJS有關(guān),但翻譯跟翻譯文章的差異很大,有很多東西要考慮致性和連貫性。本書內(nèi)容豐富,從零開始向讀者講述AnguarJS,首先介紹AnguarJS的基本概念,以及在些場景下的簡單應(yīng)用。接著,本書花很大篇幅講解AnguarJS的周邊體系。我們使用這樣個框架,自然需要對前端的架構(gòu)有些考慮,包括代碼的組織,些第庫的選擇,甚至還有項目的建立、開發(fā)、測試、發(fā)布等各環(huán)節(jié)的綜合考慮,這不再是個簡單的編碼過程,而是整套工程化的流程。另外,我們也可能需要為這樣套前端的技術(shù)棧選擇相應(yīng)的后端服務(wù),比如,可以使用Node.js自己建立,或者是利用互聯(lián)網(wǎng)上已有的些強大平AnguarJS的些原理和拓展,比如、移動開發(fā)、調(diào)試、性能優(yōu)化等無論是零基礎(chǔ)的級開發(fā)者,還是有 目前,前端MV*框架百花齊放,AnguarJS只是其中較流行的種。這些框架孰優(yōu)孰劣,其實并無定論,每個框架都會有它的適用場景,都有它優(yōu)秀的面,也沒有哪個框架能夠通吃所有業(yè)務(wù)場景,如果因為對個框架的喜愛,而把它引入到不適合的產(chǎn)品中,定是有害無益。因此,我們希望讀者在閱讀本書時,能夠多思考,愿大家在學(xué)習(xí)本書過程中都能收獲滿滿。這樣的話,作為本書譯者的我們也將感同身受,與大家同其中的喜悅和滿足感。在本書的過程中,除了我們?nèi)g者之外,公司的編輯李靜也付出了很大的努力,支付寶的玉伯、51JS版主寶玉、的berg提出了不少寶貴意見,對此,并表示衷心感謝。何鵬飛的個人致
2014年7感謝公司的團隊,本書的離不開他們的努力和幫助。最后,還要感謝沒有在這 列出的幫助過我的 個人野的個人致b技術(shù)日新月異,每天早上翻看各種技術(shù)博客,都有種逆水行舟不進則退的感,而這兩年來前V框架無疑b前端開發(fā)領(lǐng)域最熱門的話題之AuS不及待地推薦給所有想學(xué)AuS的朋友。感謝李松峰老師的幫助,感謝團隊的辛勤工作,感謝在翻譯本書過程中給予幫助的所朋友。序似乎每天都有新的JavaScrpt庫或框架發(fā)布,對此我多少已經(jīng)有些麻木了。有能力從眾多的庫或框架中進行篩選是件好事,但至少在我看來,個 來說卻是件壞事。隨著應(yīng)用程序中數(shù)量的增加,間會產(chǎn)生依賴關(guān)系,所以我直期待能有那么到兩個,就提供我需要的所 當我第次聽說AnguarJS時,它就立刻引起了我的注意,因為它只通過個獨立的框架就可以構(gòu)建動態(tài)、交互密集型的客戶端應(yīng)用。通過進步的研究,我確信這個第判斷是正確的,于是開始迷上了這個框架。AnguarJS提供了系列健壯的功能,以及將代碼成模塊的方基于個框架進行開發(fā)雖然很方便,但是學(xué)習(xí)它卻充滿。開始學(xué)習(xí)AnguarJS時,我迷失在各種不同的中,并很快變得有些沮喪,甚至開始懷疑它到底是不是要的。服務(wù)是什么?它和工廠相比有什么區(qū)別?作用域服務(wù)是怎么同整個系統(tǒng)融合在起的?指令是什么,我為什么要使用它?將這些零碎的知識點拼在起形成大局觀是我最初要克服的。如果能有些簡明的參考資料,對于降低學(xué)習(xí)難度大有裨益。很幸運,你已經(jīng)有了這樣本優(yōu)秀的參考資料,就是你手上的這本《AnguarJS》,它將幫助你提升學(xué)習(xí)效率。本書作者將他掌握AnguarJSAnguarJS應(yīng)用的流程、服務(wù)和工廠的作用以及作用域和控制器如何協(xié)同工作等知識,那么這本書就是你所需要的。使用功能強大的進行開發(fā)是件非常有趣的事情,本書的示例將幫助你快速掌握這個框架。祝你的AnguarJS項目切順利!1個人博客和Twtter頁 為http//weblogsaspnet/dwahln和http//twttercom/DanWahln致PhpWestweSaurabhAgrawa關(guān)于本書提供了系列前沿工具,使你在很短的時間內(nèi)就可以上手創(chuàng)建令人印象深刻的Web體驗。它能幫助你解決棘手的問題,并提供了些可以立AguS用。本書本書接下來會介紹AnguarJS的工作原理,以及它與其他流行的JavaScrpt框架的差異。我們會深入討論AnguarJS應(yīng)用內(nèi)部的工作流程。最后,應(yīng)用所學(xué)的知識開發(fā)個相對復(fù)雜的應(yīng)用程序。其他建議你先看下AnguarJS的API文檔,通過它,你可以直接獲得開發(fā)AnguarJS應(yīng)用的推薦方法。同時,這個文檔肯定也是的本書 ,tFa ;$$ls>>vaj={meage: 重點文字將會加粗這個圖標表示提示。這是開發(fā) 本書提到編輯器時指的是你使用的文本編輯器,而瀏覽器就是你使用的瀏覽器。強烈建議你Googe的Chrome瀏覽器,因為它提供了個開始之前,我們還需要安裝些庫。為了運試,我們需要Karma和Node.js。最好也裝上gt,但不強求。 第1 初識本章的目標是幫助你熟悉與AnguarJS有關(guān)的些術(shù)語和技術(shù),以及它們背后相關(guān)的工作原理。即使以前從來沒有接觸過AnguarJS,通過將零碎的知識點組合在起,你也可以構(gòu)建個屬于自己的AnguarJS應(yīng)用。瀏覽器如何獲取網(wǎng)我們把互聯(lián)網(wǎng)想象 個郵局:當你想給朋友寫信時,首先要把內(nèi)容寫 當你把信送到郵局,郵件分揀機會根據(jù)和地址來判斷你的朋友住在哪里。如果他住在 算機所取代。每臺計算機都有個唯的地址,讓網(wǎng)絡(luò)可以定位到它。多個公寓房間共享同個街道地址,與此類似,多臺計算機也可以共享同個網(wǎng)絡(luò)或路由器。比如,在使用星巴克提供的免費WF時,多臺計算機就會共享同個公網(wǎng)IP地址。盡管如此,你的計算機依然可以通過路由器分配的內(nèi)網(wǎng)IP地址被單獨到,路由器就好比公寓大樓的工作人2001:0db8:0000:0000:0000:ff00:0042:8329當你打開個瀏覽器,并在地址欄輸入后,瀏覽器會“詢問”網(wǎng)絡(luò)(更準確地說,是“詢問”DNS服務(wù)器)goog 址是什么?如果DNS服務(wù)器知道你要找的IP地址,就會將其結(jié)果返回;如果不知道,它會將請求轉(zhuǎn)發(fā)給其他DNS服務(wù)器,直到在某臺DNS服務(wù)$d$d如果你使用的是Mac操作系統(tǒng),可以使用Termna終端程序,它通常在/Appcatons/Uttes DNS服務(wù)器返回了你要的計算機的IP地址(例如找到了goog 對應(yīng)的IP地址)后,它就會向這個IP地址對應(yīng)的計算機請求你要的每個路徑對應(yīng)的網(wǎng)頁都由不同的HTML文檔組成(也有些例外)。例如,當瀏覽器請求或/mages時,得到的HTML文檔是不樣的。現(xiàn)在,計算機已經(jīng)知道了在哪個IP地址可以到,它會向Googe的服務(wù)器請求顯示這個頁面所需的HTML當服務(wù)器把HTML文檔發(fā)送回來后,瀏覽器會對文檔進行渲染。渲染就是通過系列操作,使HTML頁面按照設(shè)計之初的既定方式顯示瀏覽器是什目前市場上有很多不同品牌的瀏覽器,常見的有Chrome、Safar、Frefox和IE。它們的功能基本上都是相同的:獲取網(wǎng)頁,并將它顯示給瀏覽器獲取頁面對應(yīng)的HTML文本,將其解析為個在瀏覽器的結(jié)構(gòu),對頁面的內(nèi)容進行布局,并在內(nèi)容顯示到屏幕上之前加上樣式,ebAguSb應(yīng)用之間的交互。AngularJS是什AnguarJS的開發(fā)團隊將其描述為種構(gòu)建動態(tài)WebAnguarJS使開發(fā)Web應(yīng)用變得非常簡單,同時也降低了構(gòu)建復(fù)雜應(yīng)用的難度。它提供了開發(fā)者在現(xiàn)代Web應(yīng)用中經(jīng)常要用到的系列高級功能,瀏覽歷史(使書簽和前進、后退按鈕能夠像在普通Web應(yīng)用中樣工作);AngularJS中插入個按H;l,l;;盡管這個過程并不復(fù)雜,但是它要求開發(fā)者對整個DOM結(jié)構(gòu)都有所了解,并強迫我們在JavaScrpt代碼中加入復(fù)雜的控制邏輯,用以操作外部利用它,開發(fā)者可將頁面的部分封裝為個應(yīng)用,并且不強迫整個頁面都使用AnguarJS進行開發(fā)。這個特質(zhì)在某些情況下非常有用,比如你的工作流程中已經(jīng)包含了另外個框架,或者你只希望頁面中的某部分是動態(tài)的,而剩下的部分是靜態(tài)的或者是由其他JavaScrpt框架來控制的。此外,AnguarJS團隊非常重視框架文件壓縮后的大小,這樣使用它就不會付出太多的額外代價(寫作本書時,文件壓縮后的體積在90KB左右)。這特性使得AnguarJS非常適合用于開發(fā)功能原型。為了促進大家為AngurJS貢獻代碼,開發(fā)團隊把開發(fā)流程變得相對開放。任何重大變化都需要在AngurJS的郵件列表上1進行討論,所有人都可以加入討論,這樣來大家就可以對潛在的變動進行改進,并且防止重復(fù)勞動。第2 oCYPE>lngCYPE>lngSe><scpts.c" e<h o{{name}}</h>雖然這個例子不怎么有趣,但它展示了AnguarJS最基本也最令人印象深刻的功能之:數(shù)據(jù)在Ras等傳統(tǒng)Web框架中,控制器將多個模型中的數(shù)據(jù)和模板組合在起形成視圖,并將其提供給用戶,這個組合過程會產(chǎn)生個單向視圖。如果沒有創(chuàng)建任何自定義的JavaScrpt組件,視圖只會體現(xiàn)它渲染時模型出的數(shù)據(jù)。在寫這篇文章時,已經(jīng)出現(xiàn)了好幾個可以在視圖和模型AnguarJS則采用了完全不同的解決方案。它創(chuàng)建實時模板來代替視圖,而不是將數(shù)據(jù)合并進模板之后更新DOM。任何個獨立視圖組件中的值都是動態(tài)替換的。這個功能可以說是AnguarJS中最重要的功能之,也是讓我們只用10行代碼,并且在沒有任何JavaScrpt的情況下就可以寫出HeoWord的關(guān)鍵。要實現(xiàn)這個功能,只要頁面中angular.js,并在某D元素上明確設(shè)置ng-app屬性即可。ng-app屬性所有被其包含的AguSbAuS應(yīng)用的原因。只有被具有ng-appD元素包含的元素才AguS影響。 個或多個變量 態(tài)替換,替換結(jié)果是字符串中的插值被變量的值替代例如,如果有個叫做name的變量,它的值是“Ar”,那么視圖中的" o{{name}}"字符串會被替換成“HeoAr”義的代碼,它就可以工作。在MVC(ModeVewControer,模型-視圖-控制器)MVC是種軟件架構(gòu)設(shè)計模式,它將表現(xiàn)從用戶交互中分離出來。通常來講,模型中包含應(yīng)用的數(shù)據(jù)和與數(shù)據(jù)進行交互的方法,視這種表現(xiàn)分離1能將應(yīng)用中的對象很好地 開來,因此視圖不需要知道如何保存對象,只要知道如何顯示它即可。這也意味著數(shù)據(jù)模型不需要同視圖進行交互,只需要包含數(shù)據(jù)和操作視圖的方法??刂破饔脕泶娣艑⒍呓壎ㄔ谄鸬臉I(yè)務(wù)邏輯。1http//martnfowlercom/eaaDev/SeparatedPresentaton當AnguarJS認為某個值可能發(fā)生變化時,它會運行自己的循環(huán)來檢查這個值是否變“臟”。如果該值從上次循環(huán)運行之后發(fā)生了變化,這個循環(huán)會調(diào)用$dges()循環(huán),第23章將會詳細介紹這個過程被稱作臟檢查(drtycheckng)。臟檢查是檢查數(shù)據(jù)模型變化的有效。當有潛在的變化存在時,AnguarJS會在循環(huán)時執(zhí)行臟檢查(第24章會深入討論)來保證數(shù)據(jù)的致性。 和大量的觸發(fā)(eventfrng)是非常復(fù)雜的,而且會在應(yīng)用程序UI性能方面導(dǎo)致額外的問題。 盡管存在更高效的方式,但臟檢查可以運行在所有瀏覽器中并且是可預(yù)測的。此外,很多在速度和效率方面有要求的軟件都 號,你都可以只把它看作個Anguar對象。簡單的數(shù)據(jù)綁審閱下上面寫的代碼,我們使用ng-oel指令將內(nèi)部數(shù)據(jù)模型對象($scope)中的name屬性(property)綁定到了文本輸入字段上。數(shù)據(jù)模型對象(modeobject)是指$scope對象。$scope對象是個簡單的JavaScrpt對象,其中的屬性可以被視圖訪雙向數(shù)據(jù)綁定(b-drectona)意味著如果視圖改變了某個值,數(shù)據(jù)模型會通過臟檢查觀察到這個變化,而如果數(shù)據(jù)模型改變了某e"e<h o{{pee}}</h這樣綁定就設(shè)置好了(沒錯,就是這么簡單)ae我們僅通過視圖就實現(xiàn)了個雙向數(shù)據(jù)綁定。為了從其他角度(后端到前端)命名你的應(yīng) 個值來命名你的應(yīng)用。注意,下面的代碼中將l中的ng-app屬性改變成了ng- "App"從技術(shù)上講,當我們談到ng-app"yp"時,我們的意思是告訴Anguar在這里我們想要使用哪個模塊。 CYPE><lngmSe><scpts"<h o{{name}}</h></bod>ace正如ng-app所有被它包含的元素都屬于AnguarJS應(yīng)用樣,DOM元素上的ng-otroer屬性所有被它包含的元素都屬于某個<d<dvngcontolleMContollee" e<h>o{{peonne}}</h</dCYPE><lngmSe><scpts"</d>ace<hoede.m,tM//你可以將這些代碼放在通過htm文檔加載的JavaScrpt文件中或者內(nèi)聯(lián)的<scrt t 但是在真實的應(yīng)用中你定會想使用分離的.js文件來組織JavaScrpt代碼。' 塊。aguar.modue()函數(shù)返 行代碼中,我們在模塊上調(diào)用了contler函數(shù)cotoe()函數(shù)定義了個新的控制器。它接受兩個參數(shù):第個參數(shù)yContoler是第二個參數(shù)是個函數(shù)定義,它定義了這個控制器將如何工作。本書將會對這類型的函數(shù)做討論JavaScrpt允許我們使用句點(.)字符分割新行。也就是說上面的代碼與aguar.odue('Ap',])cotroller'Myotroler',...)是樣的。(這里我們使用...表示沒有顯示的代碼,這并不是真正的JavaScrpt語法)。CYPE><lngmSe><scptsc="ac"</de<h o{{name}}</hcm,tM//</sc>滴m,tM{vaudtlck=functon()cpk=new;t{;},;改變Myotollr在這個示例中,MyController函數(shù)定義接受兩個參數(shù),D元素的$scope對象和$timeout。從技術(shù)上講這叫作依賴注入。不要擔(dān)心這個奇怪的術(shù)語:它只是ue(或者)章會使用很多強大的庫。在控制器代碼中,定時器的觸發(fā)會調(diào)用datec函數(shù),它會將新的scop.coc$teot第個是個間歇調(diào)用的函數(shù); 次調(diào)用dateoc的函數(shù)在updateClock$scope.clock賦值為newDate()$scopeAu。在后面的章節(jié)中我們會深入討$scope?,F(xiàn)在,只需知道當為特殊變$scope分配些信息時,你可以在你視圖中這些信息。為了在HTML視圖中展示這個$scoecock></dSr代碼的MyController$scope.clock分配了個值。但是在我們的視圖中只指定了clock來該值(而不$scope.clock)。這是因為這e隱含在視圖中。稍后我們會討論關(guān)于它如何工作的信息。讓我們先從上個示例中移除nut和h1,此時我們的Webapp示例看起來應(yīng)該像這樣><lngm<scptsc="amc<h o{{clock}}!</h</dangula.modle'm',[])tM{vaudtlck=functon()cpk=new;t{;},;</sc>示例:/xavua/1/ed雖然上面的代碼工作在個獨立的文件中,但它導(dǎo)致這個Webapp很難與其他人進行協(xié)作開發(fā)或者很難分離出不同功能的組件。因此不要將所有代碼都包含在ndex.htm文件中,通常更好的做法是將JavaScrpt放在單獨的文件中。><lngm<scptsc="amc<h o{{clock}}!</h</dcc>////sm,tM,){vaudtlck=functon()cpk=new;t{;},數(shù)據(jù)綁定的最佳實由于JavaScrpt自身的特點,以及它在傳遞值和時的不同處理方式,通常認為,在視圖中通過對象的屬性而非對象本身來進行綁定,><tlg<scpts<h o{{cck.nw}}!</h.c</dcc>在這個例子中,相比每秒鐘都更$scope.clock,更clock.now的值會是更好的選擇。有了這個優(yōu)化后,對反映數(shù)據(jù)變化的邏輯進行如下修改:////在appsm,tM,)kvaplk=functon()$cpeclcknw=new;t{;},;第3 在JavaScrpt中,將函數(shù)代碼全部都定義在全局命名空間中絕對不是什么好主意,這樣做會導(dǎo)致從而使調(diào)試變得非常,浪費寶貴的開本章將討論如何寫出高效、能用在生產(chǎn)環(huán)境中的控制器代碼,并把它封裝 個我們稱之為模塊(modue)的單元內(nèi)在AnguarJS中,模塊是定義應(yīng)用的最主要方式。模塊包含了主要的應(yīng)用代碼。個應(yīng)用可以包含多個模塊,每個模塊都包含了定義具體功能的編寫測試代碼更容易,并能保持其清潔,以便更容易找到互相的功能AuS允許我們使angular.module()方法來模塊,這個方法能夠接受兩個參數(shù),第個是模塊的名稱,第二個是依賴列表,也就是可以被注入到模塊中的對象列表。m,調(diào)用這個方法時如果只傳遞個參數(shù),就可以用它來模塊。例如,可以通過以下代碼來myApp模塊m)這個方法相當于AnguarJS模塊的getter方法,用來獲取對模塊的 接下來,就可以在agular.moue('yAp')返回的對象上創(chuàng)建我們的應(yīng)用了開發(fā)大型應(yīng)用時,我們會創(chuàng)建多個模塊來承載業(yè)務(wù)邏輯。將復(fù)雜的功能分割成不同的模塊,有助于單獨為它們編寫測試,相關(guān)信息參見第章。參下面是anguaode()name(字符串requires(字符串數(shù)組requires包含了個字符串變量組成的列表,每個元素都是個模塊名稱,本模塊依賴于這些模塊,依賴需要在本模塊加載之前由注入器進行預(yù)第4 應(yīng)用的作用域是和應(yīng)用的數(shù)據(jù)模型相關(guān)聯(lián)的,同時作用域也是表達式執(zhí)行的上下文。$scope性的地方。作用域是視圖和控制器之間的膠水。在應(yīng)用將視圖渲染并呈獻給用戶之前,視圖中的模板會和作用域進行連接,然后應(yīng)用會對DOM進行設(shè)置以便將屬性變化通知給AnguarJS。這個功能讓XHR請求等promse對象的實現(xiàn)變得非常容易。查看第17章獲取關(guān)于promse對象的內(nèi)容。作用域是應(yīng)用狀態(tài)的基礎(chǔ)?;趧?scope$scope在其發(fā)生變化時立刻重新渲染視圖。SrSr中,當創(chuàng)建個新的執(zhí)行上下文時,實際上是用函數(shù)創(chuàng)建了AguS$scopeD元素創(chuàng)建新的作用域時,實際上是為子D元素創(chuàng)建了個新的執(zhí)行上下文。監(jiān)apply的上下文中定義和執(zhí)行表達式,同時它也是將通知給另個控制器和應(yīng)用其他部分的中介。$rootScopeAguS$rootScopeSrp的全局作用域是樣的。$scope對象就是個普通的JavaScrpt $scope的所有屬性,都可以自動被視圖到。假設(shè)我們有如下的<d<dvngppm<h o{{name}}</h</d我們希望{{name}}變量是本地$scope的個屬性,效果如圖4-1m,eo;
owo> o{{name值綁定:模板語法{{}}可以將表達式綁定到視圖上。作用域能做什以進行嵌套,業(yè)務(wù)功能和數(shù)據(jù);作用域包含了渲染視圖時所需的功能和數(shù)據(jù),它是所有視圖的唯??梢詫⒆饔糜蚶斫獬梢晥D模型(vewmode)。前 個name變量并在視圖中了它:m,eo;<d<dvngppm<h o{{name}}</h</d我們可以不將變量設(shè)置在$rootScope上,而是用控制器顯式創(chuàng)建個的子$scope對象,把它設(shè)置到這個子對象上。使用ng-cotole指令可以將個控制器對象附加到DOM元素上,如下所示:<d<dvngppm<h o{{name}}</h</d</d我們可以創(chuàng) m,tMeng-otroer指令為這個DOM元素創(chuàng)建 個新的$scope對象,并將它嵌套在$rootScope中$scope的生命周 發(fā)生在瀏覽器中時,比如用戶在通過ng-oe屬性的輸入字段中輸入,或者帶有ng-click屬性的按鈕被點擊 第6章將深入討論表達式。作用域的表達式就是賦值給作用域?qū)ο蟮淖兞?。當我們給上面提到的作用域中的name變量賦值,比如$scoea"Ar"實際上是設(shè)置了個表達式,即使這個值只是個簡單的字符串。 Agu開始運行時,所有$scope對象都會附加或者到視圖中。所有創(chuàng)$scope對象的函數(shù)也會將自身附加到視圖中。這些作用域?qū)嗀u應(yīng)用上下文中發(fā)生變化時需要運行的函數(shù)。這些函數(shù)被稱為t函數(shù),Anguar通過這些函數(shù)獲知何時啟動循環(huán)當循環(huán)運行時,它通常執(zhí)行在頂$scope對象上(被稱$rootScope),每個子作用域都執(zhí)行自己的臟值檢測。每個函數(shù)都會檢$scope對象就會觸發(fā)指定的回調(diào)函數(shù)。 盡管不會需要清理作用域(因Agu會為你處理),但是知道是誰創(chuàng)建了這個作用域還是有用的,因為你可以使用這個$scope上叫$destory()的方法來清理這個作用域。指令和作用AguS$scope,但也有例外。比如ng-controller和ng-repeat指令會創(chuàng)建自己的子D元素上。第5 當我們在頁面上創(chuàng)建個新的控制器時,AnguarJS會生成并傳遞個新的$scope給這個控制器??梢栽谶@個控制器里初始化$scope,tFe;[Name]Controller[Name]Ctrl是最佳實踐。正如我們看到的那樣,AguS會在創(chuàng)建作用域時調(diào)用控制器方法。只需創(chuàng)建控制器作用域中的函數(shù),就能創(chuàng)建可以在視圖中使用的自定義操作。很幸運,AnguarJS允許我們在視圖中像調(diào)用普通數(shù)據(jù)樣調(diào)用內(nèi)置指令ng-click可以將按鈕、等其他任何DOM元素同點擊進行綁定。ng-click指令將瀏覽器中的mouseup,同設(shè)置在DOM元素上的處理程序綁定在起(例如,當瀏覽器在某個DOM元素上觸發(fā)了點擊,函數(shù)就會被調(diào)用)。和前面的例子類似,綁定看<d<dvngcontolle="FstContolle<h4>hesltaddngmachneeve>n:</d按鈕和都被綁定在了內(nèi)部$scope的個操作上,當點擊任何個元素時AnguarJS都會調(diào)用相應(yīng)的方法。注意,當設(shè)置調(diào)用哪個函數(shù)時,會同時用括號傳遞個參數(shù)(add(1))。下面給FtCotoler添加個操作:tFe; ;t)e ;add()subtract()FirstController的作用域中,或其父級$scope中。盡可能地精簡控制器是很好的做法。作為AnguarJS開發(fā)者,使用依賴注入來服務(wù)可以實現(xiàn)這個目的。會在第14章深入AnguarJS同其他JavaScrpt框架最主要的個區(qū)別就是,控制器并不適合用來執(zhí)行DOM操作、格式化或數(shù)據(jù)操作,以及除數(shù)據(jù)模型之外的狀態(tài)操作。它只是視圖和$scope之間的橋梁。tMcop.eson{:ALenetMcop.eson{:ALene在擁有ng-contoler'Myotroer'這個屬性的元素內(nèi)部的任何子元素中,都可以 對象,因為它是定義在$scope上例如,可以方便地在視圖 .name效果如圖5-1所示<d<dvngppm<h>{{peson}}</h>andthee:<h2>{{pese</d</d正如看到的這樣$scope對象用來從數(shù)據(jù)模型向視圖傳遞信息。同時,它也可以用來設(shè)置器,同應(yīng)用的其他部分進行交互,以及建與應(yīng)用相關(guān)的特定業(yè)務(wù)邏輯??刂破髑短祝ㄗ饔糜虬饔糜?有個例外:在指令內(nèi)部創(chuàng)建的作用域被稱作孤立作用域。除了孤立作用域外,所有的作用域都通過原型繼承而來,也就是說它們都可以父級作用域。如果熟悉面向?qū)ο缶幊?,對這個機制應(yīng)該不陌生。作用域直向上尋找,直到抵達$rootScope為止。如果在$rootScope中也找不到,程序會繼續(xù)運行,但視圖無法更新。通過例子來看下這個行為。創(chuàng) 個PaetCotoller其中包 個user對象,再創(chuàng) 個CidConter來這個對象tae:tha o=functon()eeA Lene如果Chlotoler置于aentContole內(nèi)部,那hiotole的$scope對象的父級作用域<dvngcontolle="Chtolle<angcl </d{{peson</d<dvngcontolle="Chtolle<angcl </d{{peson</d
我們可以看到,點擊按鈕時,可以在Chldotoer中aetotole中$scoe 在Chldotoer的$scope中樣??刂破鲬?yīng)該盡可能保持短小精悍,而在控制器中進行DOM操作和數(shù)據(jù)操作則是個不好的實踐。m,tMg;ggg;lg:Sg,data:{use:}t//設(shè)計良好的應(yīng)用會將復(fù)雜的邏輯放到指令和服務(wù)中。通過使用指令和服務(wù),我們可以將控制器重構(gòu)成個輕量且更易的形式:簡m,tMe.ogn=functon(use{UseS.unLogn(use第6 前面已經(jīng)見過使用表達式的示例。用{{}}符號將個變量綁定到$scope上的寫法本質(zhì)上就是個表達式:{{xeion}}當使用{{}}$watch$watch函數(shù)會$scope何方式改變時,它就會調(diào)用相應(yīng)的函數(shù)。你也可以在$scope上的任意屬性發(fā)生變化時用$watch函數(shù)直接執(zhí)行某個自定義函數(shù)。3$watch函數(shù)?,F(xiàn)在,你只需知道它是為了告訴應(yīng)用程序注意變量和函數(shù)。表達式和ea(avacrpt)非常相似,但是由于表達式由AngurJ式都在其所屬的作用域內(nèi)部執(zhí)行,并有本$scope的權(quán)限;如果表達式發(fā)生了TypeError和ReferenceError并不會拋出異常;(e用、將變量應(yīng)用到數(shù)學(xué)表達式中等操作。解析AngularJS表盡管AnguarJS會在運行$gestAuS通過$parse這個內(nèi)部服務(wù)來進行表達式的運算,這個服務(wù)能夠當前所處的作用域。這個過程允許我們定義在$scope上的Sr數(shù)據(jù)和函數(shù)。$parse服務(wù)注入到控制器中,然后調(diào)用它就可以實現(xiàn)手動解析表達式。舉例來說,如果頁面上有expr示:ptle="Enteanexpesson"<h2>{{pae</d我們可以在yCotoler中給expr這個表達式設(shè)置個$atchm,tMap,,l)//用該表達式設(shè)置pavapaseFun=$pa;//cale=pa;}插要在字符串模板中做插值操作,需要在你的對象中注入ntepate服務(wù)。在下面的例子中,會將它注入 m,tM,)//我們同時擁 $scope和$nteplae服務(wù)的權(quán)$ntepottext(字符串 個包含字符插值標記的字符串mustHaveExpression(布爾型):true,當傳入的字符串中不含有表達式時會返回null。trustedContext(字符串)AguS$sce.getTrusted()方法進行嚴格的上下文轉(zhuǎn)義。查看29.4節(jié)以獲得關(guān)于最后個參數(shù)的細節(jié)內(nèi)容$ntepate服務(wù)返 時進行字符插值操作并將結(jié)果展示出來。"tpe="emaead<pe>{{pevewext}}</p</d為了確保每Body變化后更新previewText,我們需要設(shè)置$watch。3章會深入討$watch方法。完整起見,這里我們會$watch屬性中。在控制器中,我們設(shè)置了$w來監(jiān)視郵件正文的變化,并 Body屬性的值進行字符插值后的結(jié)果賦值給peeet屬性m,tM,)//ad{f(bod)va te=$nteltebdcpevewext= {:;}實例:/oDeFuCAW/1/edt?htm,js,output現(xiàn)在,在{{pevewText}}內(nèi)部的文本中可以將{{to}}當做如果需要在文本中使用不同于{{}}的符號來標識表達式的開始和結(jié)束,可以在$iteroateProder中配置。用startSbol()方法可以修改標識開始的符號。這個方法接受個參數(shù)。用eybo()方法可以修改標識結(jié)束的符號。這個方法也接受個參數(shù):$interpolateProvider注入進去。下面我們來創(chuàng)建4章會對服務(wù)進行深入討論。aaf$a'$nteltPovdeSmo'oaa$,etunpase:functo,context){vam te=$ntepltetet);etuntm }現(xiàn)在,我們已經(jīng)創(chuàng)建 m,aatM,a,//ad{f(bod)pa{:o}現(xiàn)在用自定義 符號取代默認語法中的{{}}符號來請求插值文本,因此需要將HTML修改成用這個符號取代{{}}的版本,效果如圖6-1<d<dvd="emadto"tpe="emal"cle="Recpent"<textaeanglad"></texta</d<d<dvaPev<p pevew </p</d實例:/vuJEXI/1/edt第7 在HTML中的模板綁定符號{{}}內(nèi)通過符號來調(diào)用過濾器。例如,假設(shè)我們希望將字符串轉(zhuǎn)換成大寫,可以對字符串中的每個字符都單獨進{{{{nameuppecase在 pt代碼中使用oerae過濾器tt,ffunct$sc,$flte){eeA入冒號。例如,數(shù)值過濾器可以限制小數(shù)點后的位數(shù),在過濾器后寫上:2可以將2作為參數(shù)傳給過濾器: 顯示:6 {{9numbe2可以用符號作為分割符來同時使用多個過濾器,后面介紹自定義過濾器時就會看到相關(guān)的例子。我們先來介紹AnguarJS 個數(shù)值格式化為貨幣格式。用{{123 currency}}來將123轉(zhuǎn)化成貨幣格式。dateAguS中內(nèi)置了幾種日期格式,如果沒有指定使用任何格式,默認會采用mediumDate格式,下面的例子中展示了這個格式。{{{{{{{{{{{{{{{{{{'md'dt'sot'''d'o'd'o'四位年份:四位年份:toda兩位年份:toda位年份:{{toda'''英文月份:英文月份:{{ '英文月份簡寫:{{ 'M'}}<!--Aug--數(shù)字月份:{{ '}}<!--08--年中的第幾個月份:{{ '}}<!--8--個月中的第幾天:{{ '英文星期:{{ '英文星期簡寫:{{ '}}<!--Thu--}}天中的第幾個小時:{{toda}}<!--02小時制數(shù)字小時:{{toda'}}<!--12上午或下午的第幾個小時:{{toda''}}<!--12數(shù)字分鐘數(shù):數(shù)字分鐘數(shù):{{ e''}}<!--09--個小時中的第幾分鐘:{{ te''}}<!--9--數(shù)字秒數(shù):數(shù)字秒數(shù):{{ '分鐘內(nèi)的第幾秒:{{ '毫秒數(shù):{{ '上下午標識:上下午標識:{{ '四位時區(qū)標識:{{ '下面是{{{{ ,{{ ,,'{{ 'fier過濾器可以從給定數(shù)組中選擇個子集,并將其生成個新數(shù)組返回。這個過濾器通常用來過濾需要進行展示的元素。例如,在做客戶端搜索時,可以從個數(shù)組中立刻過濾出所需的結(jié)果。這個過濾器的第個參數(shù)可以是字符串、對象或是個用來從數(shù)組中選擇元素的函數(shù)。下AuS$當作鍵名。{{{{A''eneLk''''E''Pzza']flte''如果要過濾對象,可以使用上面提到的對象過濾器。例如,如果有個由eoe對象組成的數(shù)組,每個對象都含有他們最喜歡吃的食物{{{{:ACt':'nFanc,ote:Pzza':,Ct':'nFanc,o:' o:P也可以用自定義函數(shù)進行過濾(在這個例子中函數(shù)定義在$scope上At]sCaptazed函數(shù)的功能是根據(jù)首字母是否為大寫返回true或falsecpe.sCaptalzed=functon(st{etunst[0]==sttUpe;第二個參數(shù)可以是以下三種情況之。 so過濾器可以將個JSON或JavaScrpt{{{{'':A',Ct':Fanc {"name":"Ari",}如果傳入的長度值大于作數(shù)組或字符串的長度,那么整個數(shù)組或字符串都會被返回例如,我們可以截取字符串的前三個字符:{{{{SanFancscos d lmt3{{San{{SanFancscos d lmt:6對數(shù)組也可以進行同樣的操作。返回數(shù)組的第{{{{] lmto:owecase{{{{"SanFancscos d e{{{{7 numbe2orderBy可以接受兩個參數(shù),第第個參數(shù)是用來確定數(shù)組排序方向的謂詞。下面分情況討論第個參數(shù)的類型。當?shù)趥€參數(shù)是函數(shù)時,該函數(shù)會被當作待排序?qū)ο蟮膅etter方法。在排序表達式中使用數(shù)組元素作為謂詞。對于與表達式結(jié)果并不嚴格相等的每個元素,則使用第個謂詞。第{{{{:A:''m':',:,:' odeB'ne' ]{{{{:A:''m':',:,:' odeB'am':tue ]{{{{"SanFancscos d 自定義過濾mmf,p,{etunfuncton(nput)過濾器本質(zhì)上是個會把我們輸入的內(nèi)容當作參數(shù)傳入進去的函數(shù)。上面這個例子中,我們在調(diào)用過濾器時簡單地把input理??梢栽谶@個函數(shù)中做些錯誤檢查:mfp,{etunfuncton(nput)//nput是我們傳入的字符串f(nput){e npulce(}{{gngelovesdogt' e 表要。<fo<fomnam=fo"nvllu>a </foAguS,我們不需要花太多額外的精力就可以輕松實現(xiàn)客戶端表單驗證功能。雖然b應(yīng)用安全不能完全依賴客戶端驗證,但客戶端驗證可以提供表單狀態(tài)的實時反饋。要使用表單驗證,首先要確保表單像上面的例子樣有個name下面 必填驗證某個表單輸入是否已填寫,只要在輸入字段元素上添加HTML5標記eured<<nputtpe="text"equed最小長 "最大長 "模式匹使用ng-pattern"/PATTERN/"電子郵驗證輸入內(nèi)容是否是電子郵件,只要像下面這樣將pu的類型設(shè)置 即可ea驗證輸入內(nèi)容是否是數(shù)字,將ut的類型設(shè)置為"e"驗證輸入內(nèi)容是否是URL,將ut的類型設(shè)置為e 自定義在AnguarJS中自定義指令是非常容易的。鑒于目前還沒有介紹到指令的相關(guān)內(nèi)容,第10章再深入研究如何創(chuàng)建自定義驗證。目前先來看下如何通過向后端服務(wù)器發(fā)送請求,并通過響應(yīng)的結(jié)果來將輸入字段設(shè)置為合法或不合法,以確保輸入字段中的內(nèi)容是唯的。在表單中控制如果在表單元素上綁定個ng-modelAuS$scope(注意,可以使用下面的格式這些屬性。.p未修改的.p修改過的.d合法的表如果當前輸入字段的值有效,則這個布爾屬性值為.l不合法的如果當前輸入字段的值無效,則這個布爾屬性值為.$l這是AnguarJS提供的另外個非常有用的屬性:$error對象。它包含當前表單的所有驗證內(nèi)容,以及它們是否合法的信息。用下面的語.e這些額外的屬性可應(yīng)用于單獨的輸入字段是有用的。類似的屬性同樣適用于整個表單。AnguarJS處理表單時,會根據(jù)表單當前的狀態(tài)添加些CSS類(例如當前是合法的、未發(fā)生變化的,等等),這些CSS類名和前面介紹gpstnegdtgvaldgnvald當某個字段中的輸入時.ng-nld類會被添加到這個字段上。當前例子中的站點將對應(yīng)的CSS樣式設(shè)置為utgvldbode:pxsold;}gvaldbode:pxsoldg;}當用戶同控制器進行交互,并且ngModelController$setViewValue()$parsers數(shù)組中的函數(shù)會以流水線的形式被逐個調(diào)用。第$parse$parse,以此類推。這些函數(shù)可以對輸入值進行轉(zhuǎn)換,或者通過$setVaty()函數(shù)設(shè)置表單的$parsers數(shù)組是實現(xiàn)自定義驗證的途徑之$parsers數(shù)組中入棧個新的函數(shù),這個函數(shù)會在驗證鏈中被調(diào)用。每個$parser返回的值都會被傳入 個$parser中。當不希望數(shù)據(jù)模型發(fā)生更新時返回udefedm)dectve'oeo,funct{etun,:,,,){fnMl)etu;ahVl){ =pasent(v;f(>=0&&<0)gMdl$setaldteo,te;etunvewVl;}elsele,etunundef;}}s當綁定的ngModel$parsers$formatters流水線。$parsers數(shù)組可以修改表單的狀態(tài)類似$formatters中的函數(shù)也可以修改并格式化這些值。比起單純的驗證目的,這些函數(shù)更常用來處理視圖中的可視變化。例如,假設(shè)我們要對某個值進行格式化。通過$formatters數(shù)組可以在這個值上執(zhí)行過濾器:m)dectve'oeo,funct{etun,:,,,){fnMl)etuoeh{etun$flte'me;}組合實下面我們起創(chuàng)建個表單。表單中包括用戶的名字、郵件地址以及用戶名。開始之前,首先看下我們希望這個表單長成什么樣子,如圖7-1所示。<fom<fomsgnupfom"ldatengsubmt="sgnupFo><f><ld>S>n</f></fo<dvl"<dvcl=lage<dvl"<dvcl=lage2>u><<nputte="Name"sngmlt="ngmxlegth"2"equed</d</d我們添加了個表單,這個表單有個名為name的輸入字段,并且這個輸入字段被ng-oel指令綁定到了$scope對象記給輸入字段添加name屬性。給輸入字段添加name屬性非常重要:這決定了 同時,我們也設(shè)置了些驗證。驗證要求name字段的最小長度是3個字符,最大長度是20個字符(當長度大于等于21時輸入會變?yōu)椴缓戏ǎ?。最通過使用這些屬性,可以在表單未通過驗證時控制展示或隱藏錯誤列表。用$dirty示出來:<d<dvls="<dvcl=lage2>u><nputts"ngmlt="ngmxlgt"2"equed<dvcl"eod$l<sll="eoeYounamesequ.><sll="eoem>Younamesequedtobeatleast3chaacte><sll="eoe>e></d</d</d <d<dvl"<dvcl=lage2>u><nputtpe="emaname="emal"sangmlnt="3"ngmxlgt"2"equed<dvcl"eoada$l<sll="eoYouemalsequ.><sll="eoaem>Youemalsequedtobeatleast3chaacte><sll="eoaeae><sll="eoae>e></d</d</d現(xiàn)在整個表單都被包含進來了,我們來看下電子郵件的輸入字段。注意,輸入字段的type屬性設(shè)置為 . 最后,看<d<dvcl=lage2>e>ehode="Deseduseam"nme"em"se"ngmlt="ng"ensueunque="useam"equed<dvcl"eoedsgnupfoe$ld"><sll="eoeePlenputausename><sll="eoeem>Youusenamesequedtobeatleast3chaacte><sll="eongshow="sgnupfoeeo.mxlngt>e><sll="eoeenhatusenamestk,letanothe></d</d在最后個輸入字段中除了同前面相同的驗證外,還添加了個自定義驗證。這個自定義驗證是用AnguarJSdu,{etun,:,,,t,f(!n)etu;:Su,:{'fl:att.ueUnque}tc$ldtnq,.sUnec$etldt'n',}當表單內(nèi)容通過驗證后,會向/apcheck/username發(fā)送個POSTngdsbld=sgnupfo$ld"n示例:/ePomUnI/5/edt之前提到過,表單本身會提供$iald和$ald 當用戶試圖提交表單時,你可以在作用域中捕獲到個smtt例如,修改下前面的例子,只在用戶提交表單時才顯示錯誤信息。在ng-show指令中加入對表單是否進行了提交的檢查(后面會實現(xiàn)這個功<fo<fomname="sgnupfom"ldatengsubmt="sgnupFo"<f>S><dvl"<dvcl=lage2>u><nputte"sngmlt="ngmxlegth"2"equed<dvcl"eodl<sll="eongshow="sgnupfomeo.equed">Younamesequ.><sll="eongshow="sgnupfom.nme$eoml">Younamesequedtobeatleast3chaactes><sll="eongshow="sgnupfon$eol">e></d</d</d<buttontpe="submt">Subm</f></fo現(xiàn)在,僅當signup_form.submittedtrue時,容納錯誤信息的div才會展示出來。在signupForm操作中實現(xiàn)這個行為,如下所示:tmcsgnupFom=functon()sl//}elsecsgnupfomtted=t;}如果用戶試圖在有輸入的情況下提交表單,我們現(xiàn)在可以捕獲到這個行為并展示合適的錯誤信息。示例:/ePomUnI/6/edt。在失焦后顯如果想保留實時錯誤提示的體驗,可以在用戶從某個輸入字段失焦后提示錯誤信息(例如用戶已經(jīng)不在某個特定的輸入字段中時)這個效果,需要實現(xiàn)個不是很復(fù)雜的指令,并向表單中添加個新的變量。decte'ngFocu',[funct{vaFOCUSCLASS=;estct:,,:,,,{ctfcsed=b,S;scpe$apl(functon(){ctlfcsd=t;bdu',funct.S;co$pl(functon(){}<<nputngls="eo:sgnupfomnmedt&&sgnupfo$vld}"tpe="text"e""s"ngmlt="ngmxleg="20"equedngfocusngFocus指令給表單輸入字段的lur和focus添加了對應(yīng)的行為,添加了個名為ng-focused的類,并將$focused的值設(shè)置為true<d<dvcl"eod$l>示例:/ePomUnI/7/edt也可以在ngModel控制器中使$isEmpty()方法來判斷輸入字段是否為空。當輸入字段為空這個方返true,反之如果不為空則返false。眾所周知,表單和驗證是Anguar中復(fù)雜的組件之。然而,在Anguar1.3中我們有個有用的升級用于管理表單驗證的錯誤消息,叫作ngMessages。讓我們來看個“老方式”的示例并將它與ngMessages進行比較。l"<f>S><dvl"<dvcl=lage2>u><nputt e""s"30ed$lmlee>lleo"ngshow="sgnupfom$eomunamesequedtobeatleast3chaacte><mlleo"ngshow="sgnupfonmeol>unamecannotbelgethan20chaactes></d</d</d<buttontpe="submm></fo本質(zhì)上這功能會檢查錯誤對象的狀態(tài)發(fā)生了變化。此外,我們還得到了站點中每個表單需要的很多額外的和重復(fù)的標記。這顯然不是個理想的安裝ngMessages很簡單,因為它被打包成了個Anguar模塊。首先這個模塊$$bowel saveglacaacm,;現(xiàn)在,我們已經(jīng)安裝了ngMessagesng-show指令,然后使用ngMessages的個更簡潔的實現(xiàn)替換它。l"u><nputt e""s"30<dvcl"eo"ngmsage=sgnupfomaeo<dvngmsae"equd>esueou ouname</d<dvnggmlunametbeatleast3chaactes</due</d<buttontpe="submm</fo <d<dvcl"eo"ngsage=sgnupfoaeo"ngmessagest><dvngsage"equed">sueou ouname</d<dvngg"mlunametbeatleast3chaactes</due</d 在 tes/eos.htl <dvngmessage="equed">hsfdsequed</d<dvngmessage="mlngh>hefdtbeatleast3chaactes</d>de然后我們可以通過在視圖中使用ng-meage-ncludeem ></d有時,你可能希望為不同的字段自定義錯誤信息。沒問題,你可以在這個指令內(nèi)簡單的插入個自定義錯誤信息。由于ngMessages涉esem tes/eo>></d此外,甚至還可以為自定義驗證創(chuàng)建自定義消息??梢酝ㄟ^修改模型的$parsers鏈做到這點。例如,比方說我們想要創(chuàng)建個自定義驗證器驗證用戶名在個表單中是否有效:d,{etuneque:,:a{}}對于ngModel,你可以添加可以使用ngMessage隱藏的自定義信息。還可以添加可以使用ngMessage指令檢查的帶有自定義的消息的指令。例如,改變前面使用ngMessagesl">>You><nputtpe="text" e"e"se"ngmlegt=3ngmxlngh=0equed/><dvcl"eo"ngesage=sgnupfoeeo<dvngmesge="equMakesueou ouuse</dbCheck.</delheusenamehasaleadbeenk.echoose</d</dSubmt</fo在這中用法中,我們檢查了錯誤信息的自定義屬性。為了添加自定義錯誤消息,會把它們應(yīng)用到自定義ensureUnique的ngModel中。du,{etuneque:,,,,{vaul=attssueUnque;ctlasespshfnt{f(!valvllh===0){etu;}lk;lel:Eul:ul,pa::}tlklel;tlkleletun}}第8 作為Web開發(fā)者我們都非常熟悉HTML。下面簡單回顧下并統(tǒng)我們對這個最基本的WebHTML文HTML節(jié)HTMLHTML元HTML元素由個開始和個結(jié)束組成HTML用來標記元素的開始和結(jié)束。本身用尖括號來 "aue的鍵值對設(shè)置它們,或者只設(shè)置鍵 ,它可以創(chuàng)建從個頁面到另個頁面的:很多和超樣,會有很多特殊的屬性,這些屬性就好比的 的href屬性會激活該 <a<ah "lckmetogo l>默認情況下超是藍色且有下劃線的,而按鈕在瀏覽器中看起來 超知道當自己的hre屬性被設(shè)置 之后,如果用戶點擊這個超,它應(yīng)該修改地址欄的URL并加載 最后,兩個在設(shè)置了title屬性時則有相同的行為:當用戶將鼠標懸停在元素上時會出現(xiàn)個提示框<a<ah"tllcklckmetogoll>總地來說,瀏覽器會渲染HTML元素的樣式和行為,這個能力是Web強大功能的基礎(chǔ)之任何個瀏覽器廠商,無論是Googe或Mcrosoft都盡量遵循同樣的HTML標準,以此來保證Web編程在跨設(shè)備和操作系統(tǒng)時的致性。老版本的IE瀏覽器并沒有遵循標準的HTML定義,因此我們需要些技巧才能讓其正常工作。內(nèi)容請查看第30章。近來出現(xiàn)了很多新的HTML,它們是HTML5標準的部分。例 可以定義個、剪輯或流<v<vdeoh . 指令:自定義HTML元素和屬基于我們對HTML元素的理解,指令本質(zhì)上就是AnguarJS擴展具有自定義功能的HTML元素的途徑。例如,我們可以創(chuàng)建個自定義元素,它實 >的功能并且能在所有瀏覽器中工作:<m<mbettevdeomhef="</mbettev.cgofv>注意,這個自定義元素使用了特殊的開始和閉合mybetter- 為了讓這個更有用,可以將瀏覽器默認的 <v<vdeomgofv>Canstlltakechden</v正如我們看到的那樣,指令可以和其他指令或?qū)傩越M合 為了有效了解如何將個個小組件組合成個復(fù)雜的系統(tǒng),首先要了解更基礎(chǔ)的內(nèi)容。接下來幾節(jié)的目標就是幫助你了解這些基礎(chǔ)內(nèi)容,我們開始HTML引當瀏覽器加載個包含AnguarJS應(yīng)用的HTML時,我們只需要小段很簡單的代碼就能夠啟動AnguarJS應(yīng)用(前面的章節(jié)介紹過相關(guān)內(nèi)中要用內(nèi)置指令ng-app標記出應(yīng)用的根節(jié)點。這個指令需要以屬性的形式來使用,因此可以將它寫到任何位置,但是寫到<html>的開始上是最常規(guī)的做法:內(nèi)置指令是打包在AnguarJS內(nèi)部的指令。所有內(nèi)置指令 <<lngm>現(xiàn)在,在HTML元素中可以使用所有內(nèi)置或自定義指令了。同時,基于JavaScrpt的原型繼承機制,任何在這個根元素內(nèi)部的指令只要能夠由于指令的生命周期非常復(fù)雜,會有專門的章節(jié)來介紹。在那部分內(nèi)容中還會討論指令中哪些方法是可以作用域的,以及作用域是如何在我們的 個指學(xué)習(xí)指令最快的途徑就是親自使用它,讓我們來創(chuàng)建個自定義指令。的HTML元素,后面我們會用到它<m<mdectve></mdect假設(shè)我們已經(jīng)創(chuàng)建了個完整的HTML文檔,其中包含了AnguarJS,并且DOM中已經(jīng)用ng-app指令標識出了應(yīng)用的根元素,當AnguarJS編mDiectiem)dectvmDect,funct{etun, te:ahlckmetogo 通過AnguarJS模塊API中的diecte()方法,我們可以通過傳入個字符串和個函數(shù)來個新指令。其中字符串是這個指令的名字,指令名應(yīng)該是駝峰命名風(fēng)格的,函數(shù)應(yīng)該返回個對象。駝峰命名風(fēng)格用來將個短語寫在個單詞中,除了第個單詞外其他單詞首字母大寫,中間不加空格。例如,bumpy在我們的例子中,在HTML里使用mdirecte 指令,因此指令定義必須以Dete為名字diecte()為了盡快掌握簡單的屬性定義,我們只用了restrict和mte兩個設(shè)置項來定義指令注意,代碼和你在文本編輯器中輸入的沒有區(qū)別,同時其中并沒有個。但的確屏幕上有個寫著“CckHere“,這是怎么回事?為了分析這個現(xiàn)象,,在彈出菜單中選擇InspectEement,如圖8-3所示。圖8-3InspectE默認情況下,AnguarJS將模板生成的HTML代碼嵌套在自定義<my-dietie>內(nèi)部下面向指令定義中添加些新的設(shè)置:我們可以將自定義從生成的DOM中完全移除掉,并只留下由模版生成的。將rece設(shè)置m,dectvmDect,funct{etunestct:, te:ah"lckmetogo再次看下生成后的代碼,會發(fā)現(xiàn)DOM中原始的指令已經(jīng)不見了,只有我們在模板中寫的HTML代碼。rece方用自定義元素取代從現(xiàn)在起,我們把創(chuàng)建的這些自定義元素稱作指令(用.directive方法創(chuàng)建),因為事實上指令并不需要創(chuàng)建個新的自定義元素指令本質(zhì)上是在HTML中通過元素、屬性、類或注釋來添加功能。<m<mdect<dvmdect<dvcl="mdect為了AguS能夠調(diào)用我們的指令,需要修改指令定義中的restrict設(shè)置。這個設(shè)置告AuS在編譯用哪種格式來匹配指令定義。我們可以指定個或多個格式。m,dectvmDect,funct{etunestct:', ce:t te:ah"lckmetogo<d<dvmdectve></d為了更加明確我們的意圖,將restrict設(shè)置為字母A(代表attrestestct:' 示例1。會發(fā)現(xiàn)盡管指 了兩次,但只出現(xiàn)了 1http//jsbncom/JAzUJE/1/ed從技術(shù)上講,可以通過在文檔頭部新的(查看第30章)來解決這個問題,但這樣做的就是,當疏忽了致性時會導(dǎo)致額外的問題。值得注意的個例外是,擴展內(nèi)L,例如AuS重載<a><form>和<input>。這些場景不會導(dǎo)致瀏覽器的兼容性問題,因為它們本身就是瀏覽器所支持的。表達<h<hngnt="geet' hegeetngs:{{geetng</h 'ood賦值給內(nèi)置指令ng-it。在表達式中,get屬性的值設(shè)置為 Word然后計算花括號內(nèi)的{{geetng}}這個表達式的值。這兩種情況都會在當前作用域中計算個普通的JavaScrpt表達式。根據(jù)這個表達式放置的位置不同,當前作用域可以是AnguarJS在應(yīng)用啟動用表達式來指我們知道指令時既可以使用表達式,也可以不使用表達式。下面回 下幾種合法的表達式<m<mdectveAtbte"somexpess</mdect<dvmdectv"smExpess</d<dvls="mdectvexpess</d dectve:mdectvesomeExpess 這里有個值得注意的問題,賦值給指令的表達式會在哪個環(huán)境中運行?要回答這個問題,首先要了解個復(fù)雜但非常重要的概念,就是當前作用當前作用域首先快速了 下由DOM通過內(nèi)置指令ng-cotole提供的作用域。這個指令的作用是在DOM中創(chuàng) and{{paentPopet}}</p><dvngcontolle="ChtolleWecan{{ootPopet}}{{paentPopet}}{{chPopetFd</dm,//使用. $.;ta//使用t ngcontolle內(nèi)部的屬//aa;thhd Fde:. a hP示例:/URuyoG/1/edt,為方便學(xué)習(xí),有些部分使用了彩色。注意,還有其他內(nèi)置指令(比如ng-include和ng-view)也會創(chuàng)建新的子作用域,這意味著它們在被調(diào)用時行為和ng-controller類似。我們在構(gòu)造自定義指令時也可以創(chuàng)建新的子作用域。向指令中傳遞回顧下如何定義指令:m,dectvmDect,funct{etun, ce:t, te:ah"lckmetogo'} 'ah ">lckmetogoto'如果不L和文本混在指令內(nèi)部,可以為其他使用我們指令的人提供更好的體驗。我們的目標是關(guān)注指令的公共接口,就像其他任何程語言樣。實際上,應(yīng)該將上面的模板轉(zhuǎn)換成可以接受兩個變量的形式:個變量L,另個是文本: te:ahef="{{mUl}}">{{mLnkext'在主HTML文檔中,可以給指令添加yUrl和 nText兩個屬性,這兩個參數(shù)會成為指令內(nèi)部作用域的屬性<d<dvmdectvemu""mlnktxt"Clckmetogo </d重新加載頁面,注意指令的部分已經(jīng)被模板代替,但是的href屬性是空的,并且尖括號內(nèi)也沒有文本,如圖8-6所示盡管簡單,共享狀態(tài)會導(dǎo)致很多其他問題。如果控制器被移除,或者在控制器的作用域中也定義了個叫yUrl的屬性,我們就被迫要修改代同之前在當前作用域介紹中介紹的繼承作用域(子作用域)不同,作用域同當前DOM的作用域是完全分隔開的。為了給這個新的對象設(shè)置屬性,我們需要顯式地通過屬性傳遞數(shù)據(jù),同在JavaScrpt或Ruby中給方法傳遞參數(shù)類似。當用如下代碼將指令的作用域設(shè)置 }實際上創(chuàng)造的是作用域。本質(zhì)上,意味著指令有了個屬于自己的$scope對象,這個對象只能在指令的方法中或指令的模板字符串中使 te:d</d,//P}}目前為止,我們直忽略了個細節(jié)。實際上不能像上面的例子那樣,在作用域?qū)ο髢?nèi)部直接設(shè)置smerpert//s'}<d<dvmdectsomepopet"Popetwth@bnd</dsomeProperty值設(shè)置為@AguSD中some-property屬性的值給新作用域?qū)ο笾械膕omeProperty屬性:'}注意,默認情況下smerpert在DOM中的映射是ome-propertyt}在這個例子中,被綁定的屬性名是omeattr而不是omeproperty<d<dvmdectsomeatt"Popetwth@bnd</d現(xiàn)在,當我們在指令模板或控制器中(之前的例子這樣做過 smerpert時,會得到DOM屬性中的值的副本 t<d</d,//cPopet設(shè)置成"Popetwth@bnd}回到,我們用屬性將數(shù)據(jù)從DOM中到指令的作用域中<d<dvmdectvemu""mlnklckmetogo m,dectvmDect,funct{etunestct:,ece:t,scope:{,' te:ah"{mUl}"''mLnkxt}}<>'示例:/eoKoDI/1/edt默認情況下約定DOM屬性和JavaScrpt中對象屬性的名字是樣的(除非對象的屬性名采用的是駝峰式寫法)tmLnkext:''}上面的作用域中的內(nèi)容是:將指令的私有屬$scope.myUrl同Dsome-attr屬性的值綁定起來。這個值既可以是硬編碼的也可Some-attr"{{expression}}"在DOM中要用omeattr代替my-<d<dvmdect"mlnktxt"Clckmetogo "</d更 <d<dvmdect'</d''在此之上,我們來看看如何創(chuàng) 注意在輸入 上使用了內(nèi)置指令ng-ode。這個指令可以將輸入文本同$scope上的mr屬性進行綁定m<dvmdectmlnktxt"Clckmetogo </d這段代碼是可以工作的,但如果文本輸入字段移到指令內(nèi)部并在另個指令中進行綁定,就無法正常工作了<d<dvmdectvesomeatt="{{mUlmlnktxt"Clckmetogo </d te:d
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025-2030年垃圾回收分揀機器人制造企業(yè)制定與實施新質(zhì)生產(chǎn)力戰(zhàn)略研究報告
- 批發(fā)業(yè)渠道沖突與協(xié)調(diào)管理考核試卷
- 印刷業(yè)知識產(chǎn)權(quán)保護考核試卷
- 2025-2030年地?zé)峁┡到y(tǒng)設(shè)計企業(yè)制定與實施新質(zhì)生產(chǎn)力戰(zhàn)略研究報告
- 2025-2030年戶外燒烤家具套裝行業(yè)深度調(diào)研及發(fā)展戰(zhàn)略咨詢報告
- 2025-2030年塑木遮陽棚與雨棚行業(yè)深度調(diào)研及發(fā)展戰(zhàn)略咨詢報告
- 2025-2030年手工拉坯陶瓷碗盤行業(yè)跨境出海戰(zhàn)略研究報告
- 交通樞紐建筑物清潔要點考核試卷
- 工業(yè)物聯(lián)網(wǎng)與制造業(yè)的數(shù)字化趨勢考核試卷
- 乳品質(zhì)量管理工具與方法考核試卷
- 醫(yī)院消防安全培訓(xùn)課件(完美版)
- 人教版(2024新版)一年級上冊數(shù)學(xué)第一單元《數(shù)學(xué)游戲》單元整體教學(xué)設(shè)計
- 魏寧海超買超賣指標公式
- 防洪防汛安全知識教育課件
- (正式版)FZ∕T 80014-2024 潔凈室服裝 通 用技術(shù)規(guī)范
- 新起點英語二年級下冊全冊教案
- 【幼兒園戶外體育活動材料投放的現(xiàn)狀調(diào)查報告(定量論文)8700字】
- 剪映專業(yè)版:PC端短視頻制作(全彩慕課版) 課件 第3章 短視頻剪輯快速入門
- 湖南省長沙市開福區(qū)青竹湖湘一外國語學(xué)校2023-2024學(xué)年九年級下學(xué)期一模歷史試題
- 帶狀皰疹與帶狀皰疹后遺神經(jīng)痛(HZ與PHN)
- 漢密爾頓抑郁和焦慮量表
評論
0/150
提交評論