angularjs權(quán)威教程譯者野_第1頁
angularjs權(quán)威教程譯者野_第2頁
angularjs權(quán)威教程譯者野_第3頁
angularjs權(quán)威教程譯者野_第4頁
angularjs權(quán)威教程譯者野_第5頁
已閱讀5頁,還剩594頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

1章初識AnguarJS2章數(shù)據(jù)綁定和第個(gè)AnguarJSWeb應(yīng)用HeoWord第3章模塊第4章作用域第5章控制器第6章表達(dá)式第7章過濾器第8章指令簡介第9章內(nèi)置指令第10章指令詳解優(yōu)先級(數(shù)值型transc11章AnguarJS第12 多重視圖和路$ocatonHTML5第13章依賴注入$njectornstantngM第14個(gè)服務(wù)servprovva15章同外界通信:XHR器設(shè)置$httpProv使用應(yīng)用$resource$resource使用Restanguar安裝使用16章XHR使用使用使用第17章promseAnguar中的prom如何創(chuàng)建個(gè)prom第18章安裝安裝調(diào)用簡單通知服務(wù)簡單服務(wù)安全令牌服務(wù)AWSJS+UserServAWSServ保存上傳到查詢 并創(chuàng)建個(gè)F包含F(xiàn)rebase和AnguarFreF$第19章測試Jasm定義個(gè)細(xì)則模擬測試個(gè)應(yīng)用建立我們的第個(gè)測試還要20

20.4對21

ngRepeatngVewngIncudengSwngCassngShow/ngHdeaddCremoveCcanceAnTweenMax/TweenL23章dgest循環(huán)和$app$watch$watchCoect$evaAsync$app第24章25章AnguarJSu-$urRouterProv創(chuàng)建個(gè)導(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.人民郵電獨(dú)家。 者,不得以任何方式本書內(nèi)容。僅限于中民境內(nèi)(中國、特別行政區(qū)和地區(qū)除外)銷售。,在上這本請幫ArLerner在上宣傳這本書。推薦本書:.we 特別感謝可愛的Q,感謝你直以來的激勵(lì),以及你在編輯方面的過人天賦。感謝我的共同創(chuàng)始人兼朋友NateMurray2年上半年,我所在的公司正在開發(fā) 個(gè)二次開發(fā)平臺,它的目標(biāo)是從數(shù)據(jù)庫開始,能自由、方便地定制業(yè)務(wù)數(shù)據(jù)、規(guī)則、流程、服務(wù)還有展現(xiàn)層。在對展現(xiàn)層的實(shí)現(xiàn)部分,我思考了很久,對其中部分技術(shù)細(xì)節(jié)還是缺乏好的思路,于是把眼光轉(zhuǎn)到開源社區(qū),無意中發(fā)現(xiàn)了AnguarJS這樣個(gè)框架,詳細(xì)之后,我認(rèn)為它在很大程度上滿足了我們的需求,繼而投入了不小的精力進(jìn)行研究 開發(fā)者王宇鵬等進(jìn)行了交流,獲得了很多有益的信息,與此同時(shí),也跟Avaon的作者司徒正美有過些討論,對前端MV*有了更深入的認(rèn)識。后來,團(tuán)隊(duì)中的大漠窮秋翻譯的《用AnguarJS開發(fā)下代Web應(yīng)用》由電子工業(yè)。作為國內(nèi)第本關(guān)于AnguarJS的譯著,它帶動(dòng)了學(xué)習(xí)和了解AnguarJS框架的浪潮,也因此與樸靈的《深入淺出Node.js》起,成為前端開發(fā)人員拓展思維和技能的兩本最受歡迎。在此期間,公司的李松峰老師發(fā)布了本書招募譯者的消息,我心里動(dòng)就聯(lián)系了他。經(jīng)過溝通之后,我與另外兩名譯者,豌豆莢的@野和騰訊的@basecss,合作翻譯本書,每人負(fù)責(zé)1/3的內(nèi)容。第次正式翻譯,我很忐忑,翻譯過程中也遇到了些。此前我雖翻譯過些技術(shù)文章,其中篇恰好與AnguarJS有關(guān),但翻譯跟翻譯文章的差異很大,有很多東西要考慮致性和連貫性。本書內(nèi)容豐富,從零開始向讀者講述AnguarJS,首先介紹AnguarJS的基本概念,以及在些場景下的簡單應(yīng)用。接著,本書花很大篇幅講解AnguarJS的周邊體系。我們使用這樣個(gè)框架,自然需要對前端的架構(gòu)有些考慮,包括代碼的組織,些第庫的選擇,甚至還有項(xiàng)目的建立、開發(fā)、測試、發(fā)布等各環(huán)節(jié)的綜合考慮,這不再是個(gè)簡單的編碼過程,而是整套工程化的流程。另外,我們也可能需要為這樣套前端的技術(shù)棧選擇相應(yīng)的后端服務(wù),比如,可以使用Node.js自己建立,或者是利用互聯(lián)網(wǎng)上已有的些強(qiáng)大平AnguarJS的些原理和拓展,比如、移動(dòng)開發(fā)、調(diào)試、性能優(yōu)化等無論是零基礎(chǔ)的級開發(fā)者,還是有 目前,前端MV*框架百花齊放,AnguarJS只是其中較流行的種。這些框架孰優(yōu)孰劣,其實(shí)并無定論,每個(gè)框架都會有它的適用場景,都有它優(yōu)秀的面,也沒有哪個(gè)框架能夠通吃所有業(yè)務(wù)場景,如果因?yàn)閷€(gè)框架的喜愛,而把它引入到不適合的產(chǎn)品中,定是有害無益。因此,我們希望讀者在閱讀本書時(shí),能夠多思考,愿大家在學(xué)習(xí)本書過程中都能收獲滿滿。這樣的話,作為本書譯者的我們也將感同身受,與大家同其中的喜悅和滿足感。在本書的過程中,除了我們?nèi)g者之外,公司的編輯李靜也付出了很大的努力,支付寶的玉伯、51JS版主寶玉、的berg提出了不少寶貴意見,對此,并表示衷心感謝。何鵬飛的個(gè)人致

2014年7感謝公司的團(tuán)隊(duì),本書的離不開他們的努力和幫助。最后,還要感謝沒有在這 列出的幫助過我的 個(gè)人野的個(gè)人致b技術(shù)日新月異,每天早上翻看各種技術(shù)博客,都有種逆水行舟不進(jìn)則退的感,而這兩年來前V框架無疑b前端開發(fā)領(lǐng)域最熱門的話題之AuS不及待地推薦給所有想學(xué)AuS的朋友。感謝李松峰老師的幫助,感謝團(tuán)隊(duì)的辛勤工作,感謝在翻譯本書過程中給予幫助的所朋友。序似乎每天都有新的JavaScrpt庫或框架發(fā)布,對此我多少已經(jīng)有些麻木了。有能力從眾多的庫或框架中進(jìn)行篩選是件好事,但至少在我看來,個(gè) 來說卻是件壞事。隨著應(yīng)用程序中數(shù)量的增加,間會產(chǎn)生依賴關(guān)系,所以我直期待能有那么到兩個(gè),就提供我需要的所 當(dāng)我第次聽說AnguarJS時(shí),它就立刻引起了我的注意,因?yàn)樗煌ㄟ^個(gè)獨(dú)立的框架就可以構(gòu)建動(dòng)態(tài)、交互密集型的客戶端應(yīng)用。通過進(jìn)步的研究,我確信這個(gè)第判斷是正確的,于是開始迷上了這個(gè)框架。AnguarJS提供了系列健壯的功能,以及將代碼成模塊的方基于個(gè)框架進(jìn)行開發(fā)雖然很方便,但是學(xué)習(xí)它卻充滿。開始學(xué)習(xí)AnguarJS時(shí),我迷失在各種不同的中,并很快變得有些沮喪,甚至開始懷疑它到底是不是要的。服務(wù)是什么?它和工廠相比有什么區(qū)別?作用域服務(wù)是怎么同整個(gè)系統(tǒng)融合在起的?指令是什么,我為什么要使用它?將這些零碎的知識點(diǎn)拼在起形成大局觀是我最初要克服的。如果能有些簡明的參考資料,對于降低學(xué)習(xí)難度大有裨益。很幸運(yùn),你已經(jīng)有了這樣本優(yōu)秀的參考資料,就是你手上的這本《AnguarJS》,它將幫助你提升學(xué)習(xí)效率。本書作者將他掌握AnguarJSAnguarJS應(yīng)用的流程、服務(wù)和工廠的作用以及作用域和控制器如何協(xié)同工作等知識,那么這本書就是你所需要的。使用功能強(qiáng)大的進(jìn)行開發(fā)是件非常有趣的事情,本書的示例將幫助你快速掌握這個(gè)框架。祝你的AnguarJS項(xiàng)目切順利!1個(gè)人博客和Twtter頁 為http//weblogsaspnet/dwahln和http//twttercom/DanWahln致PhpWestweSaurabhAgrawa關(guān)于本書提供了系列前沿工具,使你在很短的時(shí)間內(nèi)就可以上手創(chuàng)建令人印象深刻的Web體驗(yàn)。它能幫助你解決棘手的問題,并提供了些可以立AguS用。本書本書接下來會介紹AnguarJS的工作原理,以及它與其他流行的JavaScrpt框架的差異。我們會深入討論AnguarJS應(yīng)用內(nèi)部的工作流程。最后,應(yīng)用所學(xué)的知識開發(fā)個(gè)相對復(fù)雜的應(yīng)用程序。其他建議你先看下AnguarJS的API文檔,通過它,你可以直接獲得開發(fā)AnguarJS應(yīng)用的推薦方法。同時(shí),這個(gè)文檔肯定也是的本書 ,tFa ;$$ls>>vaj={meage: 重點(diǎn)文字將會加粗這個(gè)圖標(biāo)表示提示。這是開發(fā) 本書提到編輯器時(shí)指的是你使用的文本編輯器,而瀏覽器就是你使用的瀏覽器。強(qiáng)烈建議你Googe的Chrome瀏覽器,因?yàn)樗峁┝藗€(gè)開始之前,我們還需要安裝些庫。為了運(yùn)試,我們需要Karma和Node.js。最好也裝上gt,但不強(qiáng)求。 第1 初識本章的目標(biāo)是幫助你熟悉與AnguarJS有關(guān)的些術(shù)語和技術(shù),以及它們背后相關(guān)的工作原理。即使以前從來沒有接觸過AnguarJS,通過將零碎的知識點(diǎn)組合在起,你也可以構(gòu)建個(gè)屬于自己的AnguarJS應(yīng)用。瀏覽器如何獲取網(wǎng)我們把互聯(lián)網(wǎng)想象 個(gè)郵局:當(dāng)你想給朋友寫信時(shí),首先要把內(nèi)容寫 當(dāng)你把信送到郵局,郵件分揀機(jī)會根據(jù)和地址來判斷你的朋友住在哪里。如果他住在 算機(jī)所取代。每臺計(jì)算機(jī)都有個(gè)唯的地址,讓網(wǎng)絡(luò)可以定位到它。多個(gè)公寓房間共享同個(gè)街道地址,與此類似,多臺計(jì)算機(jī)也可以共享同個(gè)網(wǎng)絡(luò)或路由器。比如,在使用星巴克提供的免費(fèi)WF時(shí),多臺計(jì)算機(jī)就會共享同個(gè)公網(wǎng)IP地址。盡管如此,你的計(jì)算機(jī)依然可以通過路由器分配的內(nèi)網(wǎng)IP地址被單獨(dú)到,路由器就好比公寓大樓的工作人2001:0db8:0000:0000:0000:ff00:0042:8329當(dāng)你打開個(gè)瀏覽器,并在地址欄輸入后,瀏覽器會“詢問”網(wǎng)絡(luò)(更準(zhǔn)確地說,是“詢問”DNS服務(wù)器)goog 址是什么?如果DNS服務(wù)器知道你要找的IP地址,就會將其結(jié)果返回;如果不知道,它會將請求轉(zhuǎn)發(fā)給其他DNS服務(wù)器,直到在某臺DNS服務(wù)$d$d如果你使用的是Mac操作系統(tǒng),可以使用Termna終端程序,它通常在/Appcatons/Uttes DNS服務(wù)器返回了你要的計(jì)算機(jī)的IP地址(例如找到了goog 對應(yīng)的IP地址)后,它就會向這個(gè)IP地址對應(yīng)的計(jì)算機(jī)請求你要的每個(gè)路徑對應(yīng)的網(wǎng)頁都由不同的HTML文檔組成(也有些例外)。例如,當(dāng)瀏覽器請求或/mages時(shí),得到的HTML文檔是不樣的?,F(xiàn)在,計(jì)算機(jī)已經(jīng)知道了在哪個(gè)IP地址可以到,它會向Googe的服務(wù)器請求顯示這個(gè)頁面所需的HTML當(dāng)服務(wù)器把HTML文檔發(fā)送回來后,瀏覽器會對文檔進(jìn)行渲染。渲染就是通過系列操作,使HTML頁面按照設(shè)計(jì)之初的既定方式顯示瀏覽器是什目前市場上有很多不同品牌的瀏覽器,常見的有Chrome、Safar、Frefox和IE。它們的功能基本上都是相同的:獲取網(wǎng)頁,并將它顯示給瀏覽器獲取頁面對應(yīng)的HTML文本,將其解析為個(gè)在瀏覽器的結(jié)構(gòu),對頁面的內(nèi)容進(jìn)行布局,并在內(nèi)容顯示到屏幕上之前加上樣式,ebAguSb應(yīng)用之間的交互。AngularJS是什AnguarJS的開發(fā)團(tuán)隊(duì)將其描述為種構(gòu)建動(dòng)態(tài)WebAnguarJS使開發(fā)Web應(yīng)用變得非常簡單,同時(shí)也降低了構(gòu)建復(fù)雜應(yīng)用的難度。它提供了開發(fā)者在現(xiàn)代Web應(yīng)用中經(jīng)常要用到的系列高級功能,瀏覽歷史(使書簽和前進(jìn)、后退按鈕能夠像在普通Web應(yīng)用中樣工作);AngularJS中插入個(gè)按H;l,l;;盡管這個(gè)過程并不復(fù)雜,但是它要求開發(fā)者對整個(gè)DOM結(jié)構(gòu)都有所了解,并強(qiáng)迫我們在JavaScrpt代碼中加入復(fù)雜的控制邏輯,用以操作外部利用它,開發(fā)者可將頁面的部分封裝為個(gè)應(yīng)用,并且不強(qiáng)迫整個(gè)頁面都使用AnguarJS進(jìn)行開發(fā)。這個(gè)特質(zhì)在某些情況下非常有用,比如你的工作流程中已經(jīng)包含了另外個(gè)框架,或者你只希望頁面中的某部分是動(dòng)態(tài)的,而剩下的部分是靜態(tài)的或者是由其他JavaScrpt框架來控制的。此外,AnguarJS團(tuán)隊(duì)非常重視框架文件壓縮后的大小,這樣使用它就不會付出太多的額外代價(jià)(寫作本書時(shí),文件壓縮后的體積在90KB左右)。這特性使得AnguarJS非常適合用于開發(fā)功能原型。為了促進(jìn)大家為AngurJS貢獻(xiàn)代碼,開發(fā)團(tuán)隊(duì)把開發(fā)流程變得相對開放。任何重大變化都需要在AngurJS的郵件列表上1進(jìn)行討論,所有人都可以加入討論,這樣來大家就可以對潛在的變動(dòng)進(jìn)行改進(jìn),并且防止重復(fù)勞動(dòng)。第2 oCYPE>lngCYPE>lngSe><scpts.c" e<h o{{name}}</h>雖然這個(gè)例子不怎么有趣,但它展示了AnguarJS最基本也最令人印象深刻的功能之:數(shù)據(jù)在Ras等傳統(tǒng)Web框架中,控制器將多個(gè)模型中的數(shù)據(jù)和模板組合在起形成視圖,并將其提供給用戶,這個(gè)組合過程會產(chǎn)生個(gè)單向視圖。如果沒有創(chuàng)建任何自定義的JavaScrpt組件,視圖只會體現(xiàn)它渲染時(shí)模型出的數(shù)據(jù)。在寫這篇文章時(shí),已經(jīng)出現(xiàn)了好幾個(gè)可以在視圖和模型AnguarJS則采用了完全不同的解決方案。它創(chuàng)建實(shí)時(shí)模板來代替視圖,而不是將數(shù)據(jù)合并進(jìn)模板之后更新DOM。任何個(gè)獨(dú)立視圖組件中的值都是動(dòng)態(tài)替換的。這個(gè)功能可以說是AnguarJS中最重要的功能之,也是讓我們只用10行代碼,并且在沒有任何JavaScrpt的情況下就可以寫出HeoWord的關(guān)鍵。要實(shí)現(xiàn)這個(gè)功能,只要頁面中angular.js,并在某D元素上明確設(shè)置ng-app屬性即可。ng-app屬性所有被其包含的AguSbAuS應(yīng)用的原因。只有被具有ng-appD元素包含的元素才AguS影響。 個(gè)或多個(gè)變量 態(tài)替換,替換結(jié)果是字符串中的插值被變量的值替代例如,如果有個(gè)叫做name的變量,它的值是“Ar”,那么視圖中的" o{{name}}"字符串會被替換成“HeoAr”義的代碼,它就可以工作。在MVC(ModeVewControer,模型-視圖-控制器)MVC是種軟件架構(gòu)設(shè)計(jì)模式,它將表現(xiàn)從用戶交互中分離出來。通常來講,模型中包含應(yīng)用的數(shù)據(jù)和與數(shù)據(jù)進(jìn)行交互的方法,視這種表現(xiàn)分離1能將應(yīng)用中的對象很好地 開來,因此視圖不需要知道如何保存對象,只要知道如何顯示它即可。這也意味著數(shù)據(jù)模型不需要同視圖進(jìn)行交互,只需要包含數(shù)據(jù)和操作視圖的方法??刂破饔脕泶娣艑⒍呓壎ㄔ谄鸬臉I(yè)務(wù)邏輯。1http//martnfowlercom/eaaDev/SeparatedPresentaton當(dāng)AnguarJS認(rèn)為某個(gè)值可能發(fā)生變化時(shí),它會運(yùn)行自己的循環(huán)來檢查這個(gè)值是否變“臟”。如果該值從上次循環(huán)運(yùn)行之后發(fā)生了變化,這個(gè)循環(huán)會調(diào)用$dges()循環(huán),第23章將會詳細(xì)介紹這個(gè)過程被稱作臟檢查(drtycheckng)。臟檢查是檢查數(shù)據(jù)模型變化的有效。當(dāng)有潛在的變化存在時(shí),AnguarJS會在循環(huán)時(shí)執(zhí)行臟檢查(第24章會深入討論)來保證數(shù)據(jù)的致性。 和大量的觸發(fā)(eventfrng)是非常復(fù)雜的,而且會在應(yīng)用程序UI性能方面導(dǎo)致額外的問題。 盡管存在更高效的方式,但臟檢查可以運(yùn)行在所有瀏覽器中并且是可預(yù)測的。此外,很多在速度和效率方面有要求的軟件都 號,你都可以只把它看作個(gè)Anguar對象。簡單的數(shù)據(jù)綁審閱下上面寫的代碼,我們使用ng-oel指令將內(nèi)部數(shù)據(jù)模型對象($scope)中的name屬性(property)綁定到了文本輸入字段上。數(shù)據(jù)模型對象(modeobject)是指$scope對象。$scope對象是個(gè)簡單的JavaScrpt對象,其中的屬性可以被視圖訪雙向數(shù)據(jù)綁定(b-drectona)意味著如果視圖改變了某個(gè)值,數(shù)據(jù)模型會通過臟檢查觀察到這個(gè)變化,而如果數(shù)據(jù)模型改變了某e"e<h o{{pee}}</h這樣綁定就設(shè)置好了(沒錯(cuò),就是這么簡單)ae我們僅通過視圖就實(shí)現(xiàn)了個(gè)雙向數(shù)據(jù)綁定。為了從其他角度(后端到前端)命名你的應(yīng) 個(gè)值來命名你的應(yīng)用。注意,下面的代碼中將l中的ng-app屬性改變成了ng- "App"從技術(shù)上講,當(dāng)我們談到ng-app"yp"時(shí),我們的意思是告訴Anguar在這里我們想要使用哪個(gè)模塊。 CYPE><lngmSe><scpts"<h o{{name}}</h></bod>ace正如ng-app所有被它包含的元素都屬于AnguarJS應(yīng)用樣,DOM元素上的ng-otroer屬性所有被它包含的元素都屬于某個(gè)<d<dvngcontolleMContollee" e<h>o{{peonne}}</h</dCYPE><lngmSe><scpts"</d>ace<hoede.m,tM//你可以將這些代碼放在通過htm文檔加載的JavaScrpt文件中或者內(nèi)聯(lián)的<scrt t 但是在真實(shí)的應(yīng)用中你定會想使用分離的.js文件來組織JavaScrpt代碼。' 塊。aguar.modue()函數(shù)返 行代碼中,我們在模塊上調(diào)用了contler函數(shù)cotoe()函數(shù)定義了個(gè)新的控制器。它接受兩個(gè)參數(shù):第個(gè)參數(shù)yContoler是第二個(gè)參數(shù)是個(gè)函數(shù)定義,它定義了這個(gè)控制器將如何工作。本書將會對這類型的函數(shù)做討論JavaScrpt允許我們使用句點(diǎn)(.)字符分割新行。也就是說上面的代碼與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在這個(gè)示例中,MyController函數(shù)定義接受兩個(gè)參數(shù),D元素的$scope對象和$timeout。從技術(shù)上講這叫作依賴注入。不要擔(dān)心這個(gè)奇怪的術(shù)語:它只是ue(或者)章會使用很多強(qiáng)大的庫。在控制器代碼中,定時(shí)器的觸發(fā)會調(diào)用datec函數(shù),它會將新的scop.coc$teot第個(gè)是個(gè)間歇調(diào)用的函數(shù); 次調(diào)用dateoc的函數(shù)在updateClock$scope.clock賦值為newDate()$scopeAu。在后面的章節(jié)中我們會深入討$scope?,F(xiàn)在,只需知道當(dāng)為特殊變$scope分配些信息時(shí),你可以在你視圖中這些信息。為了在HTML視圖中展示這個(gè)$scoecock></dSr代碼的MyController$scope.clock分配了個(gè)值。但是在我們的視圖中只指定了clock來該值(而不$scope.clock)。這是因?yàn)檫@e隱含在視圖中。稍后我們會討論關(guān)于它如何工作的信息。讓我們先從上個(gè)示例中移除nut和h1,此時(shí)我們的Webapp示例看起來應(yīng)該像這樣><lngm<scptsc="amc<h o{{clock}}!</h</dangula.modle'm',[])tM{vaudtlck=functon()cpk=new;t{;},;</sc>示例:/xavua/1/ed雖然上面的代碼工作在個(gè)獨(dú)立的文件中,但它導(dǎo)致這個(gè)Webapp很難與其他人進(jìn)行協(xié)作開發(fā)或者很難分離出不同功能的組件。因此不要將所有代碼都包含在ndex.htm文件中,通常更好的做法是將JavaScrpt放在單獨(dú)的文件中。><lngm<scptsc="amc<h o{{clock}}!</h</dcc>////sm,tM,){vaudtlck=functon()cpk=new;t{;},數(shù)據(jù)綁定的最佳實(shí)由于JavaScrpt自身的特點(diǎn),以及它在傳遞值和時(shí)的不同處理方式,通常認(rèn)為,在視圖中通過對象的屬性而非對象本身來進(jìn)行綁定,><tlg<scpts<h o{{cck.nw}}!</h.c</dcc>在這個(gè)例子中,相比每秒鐘都更$scope.clock,更c(diǎn)lock.now的值會是更好的選擇。有了這個(gè)優(yōu)化后,對反映數(shù)據(jù)變化的邏輯進(jìn)行如下修改:////在appsm,tM,)kvaplk=functon()$cpeclcknw=new;t{;},;第3 在JavaScrpt中,將函數(shù)代碼全部都定義在全局命名空間中絕對不是什么好主意,這樣做會導(dǎo)致從而使調(diào)試變得非常,浪費(fèi)寶貴的開本章將討論如何寫出高效、能用在生產(chǎn)環(huán)境中的控制器代碼,并把它封裝 個(gè)我們稱之為模塊(modue)的單元內(nèi)在AnguarJS中,模塊是定義應(yīng)用的最主要方式。模塊包含了主要的應(yīng)用代碼。個(gè)應(yīng)用可以包含多個(gè)模塊,每個(gè)模塊都包含了定義具體功能的編寫測試代碼更容易,并能保持其清潔,以便更容易找到互相的功能AuS允許我們使angular.module()方法來模塊,這個(gè)方法能夠接受兩個(gè)參數(shù),第個(gè)是模塊的名稱,第二個(gè)是依賴列表,也就是可以被注入到模塊中的對象列表。m,調(diào)用這個(gè)方法時(shí)如果只傳遞個(gè)參數(shù),就可以用它來模塊。例如,可以通過以下代碼來myApp模塊m)這個(gè)方法相當(dāng)于AnguarJS模塊的getter方法,用來獲取對模塊的 接下來,就可以在agular.moue('yAp')返回的對象上創(chuàng)建我們的應(yīng)用了開發(fā)大型應(yīng)用時(shí),我們會創(chuàng)建多個(gè)模塊來承載業(yè)務(wù)邏輯。將復(fù)雜的功能分割成不同的模塊,有助于單獨(dú)為它們編寫測試,相關(guān)信息參見第章。參下面是anguaode()name(字符串requires(字符串?dāng)?shù)組requires包含了個(gè)字符串變量組成的列表,每個(gè)元素都是個(gè)模塊名稱,本模塊依賴于這些模塊,依賴需要在本模塊加載之前由注入器進(jìn)行預(yù)第4 應(yīng)用的作用域是和應(yīng)用的數(shù)據(jù)模型相關(guān)聯(lián)的,同時(shí)作用域也是表達(dá)式執(zhí)行的上下文。$scope性的地方。作用域是視圖和控制器之間的膠水。在應(yīng)用將視圖渲染并呈獻(xiàn)給用戶之前,視圖中的模板會和作用域進(jìn)行連接,然后應(yīng)用會對DOM進(jìn)行設(shè)置以便將屬性變化通知給AnguarJS。這個(gè)功能讓XHR請求等promse對象的實(shí)現(xiàn)變得非常容易。查看第17章獲取關(guān)于promse對象的內(nèi)容。作用域是應(yīng)用狀態(tài)的基礎(chǔ)。基于動(dòng)$scope$scope在其發(fā)生變化時(shí)立刻重新渲染視圖。SrSr中,當(dāng)創(chuàng)建個(gè)新的執(zhí)行上下文時(shí),實(shí)際上是用函數(shù)創(chuàng)建了AguS$scopeD元素創(chuàng)建新的作用域時(shí),實(shí)際上是為子D元素創(chuàng)建了個(gè)新的執(zhí)行上下文。監(jiān)apply的上下文中定義和執(zhí)行表達(dá)式,同時(shí)它也是將通知給另個(gè)控制器和應(yīng)用其他部分的中介。$rootScopeAguS$rootScopeSrp的全局作用域是樣的。$scope對象就是個(gè)普通的JavaScrpt $scope的所有屬性,都可以自動(dòng)被視圖到。假設(shè)我們有如下的<d<dvngppm<h o{{name}}</h</d我們希望{{name}}變量是本地$scope的個(gè)屬性,效果如圖4-1m,eo;

owo> o{{name值綁定:模板語法{{}}可以將表達(dá)式綁定到視圖上。作用域能做什以進(jìn)行嵌套,業(yè)務(wù)功能和數(shù)據(jù);作用域包含了渲染視圖時(shí)所需的功能和數(shù)據(jù),它是所有視圖的唯??梢詫⒆饔糜蚶斫獬梢晥D模型(vewmode)。前 個(gè)name變量并在視圖中了它:m,eo;<d<dvngppm<h o{{name}}</h</d我們可以不將變量設(shè)置在$rootScope上,而是用控制器顯式創(chuàng)建個(gè)的子$scope對象,把它設(shè)置到這個(gè)子對象上。使用ng-cotole指令可以將個(gè)控制器對象附加到DOM元素上,如下所示:<d<dvngppm<h o{{name}}</h</d</d我們可以創(chuàng) m,tMeng-otroer指令為這個(gè)DOM元素創(chuàng)建 個(gè)新的$scope對象,并將它嵌套在$rootScope中$scope的生命周 發(fā)生在瀏覽器中時(shí),比如用戶在通過ng-oe屬性的輸入字段中輸入,或者帶有ng-click屬性的按鈕被點(diǎn)擊 第6章將深入討論表達(dá)式。作用域的表達(dá)式就是賦值給作用域?qū)ο蟮淖兞俊.?dāng)我們給上面提到的作用域中的name變量賦值,比如$scoea"Ar"實(shí)際上是設(shè)置了個(gè)表達(dá)式,即使這個(gè)值只是個(gè)簡單的字符串。 Agu開始運(yùn)行時(shí),所有$scope對象都會附加或者到視圖中。所有創(chuàng)$scope對象的函數(shù)也會將自身附加到視圖中。這些作用域?qū)嗀u應(yīng)用上下文中發(fā)生變化時(shí)需要運(yùn)行的函數(shù)。這些函數(shù)被稱為t函數(shù),Anguar通過這些函數(shù)獲知何時(shí)啟動(dòng)循環(huán)當(dāng)循環(huán)運(yùn)行時(shí),它通常執(zhí)行在頂$scope對象上(被稱$rootScope),每個(gè)子作用域都執(zhí)行自己的臟值檢測。每個(gè)函數(shù)都會檢$scope對象就會觸發(fā)指定的回調(diào)函數(shù)。 盡管不會需要清理作用域(因Agu會為你處理),但是知道是誰創(chuàng)建了這個(gè)作用域還是有用的,因?yàn)槟憧梢允褂眠@個(gè)$scope上叫$destory()的方法來清理這個(gè)作用域。指令和作用AguS$scope,但也有例外。比如ng-controller和ng-repeat指令會創(chuàng)建自己的子D元素上。第5 當(dāng)我們在頁面上創(chuàng)建個(gè)新的控制器時(shí),AnguarJS會生成并傳遞個(gè)新的$scope給這個(gè)控制器??梢栽谶@個(gè)控制器里初始化$scope,tFe;[Name]Controller[Name]Ctrl是最佳實(shí)踐。正如我們看到的那樣,AguS會在創(chuàng)建作用域時(shí)調(diào)用控制器方法。只需創(chuàng)建控制器作用域中的函數(shù),就能創(chuàng)建可以在視圖中使用的自定義操作。很幸運(yùn),AnguarJS允許我們在視圖中像調(diào)用普通數(shù)據(jù)樣調(diào)用內(nèi)置指令ng-click可以將按鈕、等其他任何DOM元素同點(diǎn)擊進(jìn)行綁定。ng-click指令將瀏覽器中的mouseup,同設(shè)置在DOM元素上的處理程序綁定在起(例如,當(dāng)瀏覽器在某個(gè)DOM元素上觸發(fā)了點(diǎn)擊,函數(shù)就會被調(diào)用)。和前面的例子類似,綁定看<d<dvngcontolle="FstContolle<h4>hesltaddngmachneeve>n:</d按鈕和都被綁定在了內(nèi)部$scope的個(gè)操作上,當(dāng)點(diǎn)擊任何個(gè)元素時(shí)AnguarJS都會調(diào)用相應(yīng)的方法。注意,當(dāng)設(shè)置調(diào)用哪個(gè)函數(shù)時(shí),會同時(shí)用括號傳遞個(gè)參數(shù)(add(1))。下面給FtCotoler添加個(gè)操作:tFe; ;t)e ;add()subtract()FirstController的作用域中,或其父級$scope中。盡可能地精簡控制器是很好的做法。作為AnguarJS開發(fā)者,使用依賴注入來服務(wù)可以實(shí)現(xiàn)這個(gè)目的。會在第14章深入AnguarJS同其他JavaScrpt框架最主要的個(gè)區(qū)別就是,控制器并不適合用來執(zhí)行DOM操作、格式化或數(shù)據(jù)操作,以及除數(shù)據(jù)模型之外的狀態(tài)操作。它只是視圖和$scope之間的橋梁。tMcop.eson{:ALenetMcop.eson{:ALene在擁有ng-contoler'Myotroer'這個(gè)屬性的元素內(nèi)部的任何子元素中,都可以 對象,因?yàn)樗嵌x在$scope上例如,可以方便地在視圖 .name效果如圖5-1所示<d<dvngppm<h>{{peson}}</h>andthee:<h2>{{pese</d</d正如看到的這樣$scope對象用來從數(shù)據(jù)模型向視圖傳遞信息。同時(shí),它也可以用來設(shè)置器,同應(yīng)用的其他部分進(jìn)行交互,以及建與應(yīng)用相關(guān)的特定業(yè)務(wù)邏輯??刂破髑短祝ㄗ饔糜虬饔糜?有個(gè)例外:在指令內(nèi)部創(chuàng)建的作用域被稱作孤立作用域。除了孤立作用域外,所有的作用域都通過原型繼承而來,也就是說它們都可以父級作用域。如果熟悉面向?qū)ο缶幊?,對這個(gè)機(jī)制應(yīng)該不陌生。作用域直向上尋找,直到抵達(dá)$rootScope為止。如果在$rootScope中也找不到,程序會繼續(xù)運(yùn)行,但視圖無法更新。通過例子來看下這個(gè)行為。創(chuàng) 個(gè)PaetCotoller其中包 個(gè)user對象,再創(chuàng) 個(gè)CidConter來這個(gè)對象tae:tha o=functon()eeA Lene如果Chlotoler置于aentContole內(nèi)部,那hiotole的$scope對象的父級作用域<dvngcontolle="Chtolle<angcl </d{{peson</d<dvngcontolle="Chtolle<angcl </d{{peson</d

我們可以看到,點(diǎn)擊按鈕時(shí),可以在Chldotoer中aetotole中$scoe 在Chldotoer的$scope中樣??刂破鲬?yīng)該盡可能保持短小精悍,而在控制器中進(jìn)行DOM操作和數(shù)據(jù)操作則是個(gè)不好的實(shí)踐。m,tMg;ggg;lg:Sg,data:{use:}t//設(shè)計(jì)良好的應(yīng)用會將復(fù)雜的邏輯放到指令和服務(wù)中。通過使用指令和服務(wù),我們可以將控制器重構(gòu)成個(gè)輕量且更易的形式:簡m,tMe.ogn=functon(use{UseS.unLogn(use第6 前面已經(jīng)見過使用表達(dá)式的示例。用{{}}符號將個(gè)變量綁定到$scope上的寫法本質(zhì)上就是個(gè)表達(dá)式:{{xeion}}當(dāng)使用{{}}$watch$watch函數(shù)會$scope何方式改變時(shí),它就會調(diào)用相應(yīng)的函數(shù)。你也可以在$scope上的任意屬性發(fā)生變化時(shí)用$watch函數(shù)直接執(zhí)行某個(gè)自定義函數(shù)。3$watch函數(shù)。現(xiàn)在,你只需知道它是為了告訴應(yīng)用程序注意變量和函數(shù)。表達(dá)式和ea(avacrpt)非常相似,但是由于表達(dá)式由AngurJ式都在其所屬的作用域內(nèi)部執(zhí)行,并有本$scope的權(quán)限;如果表達(dá)式發(fā)生了TypeError和ReferenceError并不會拋出異常;(e用、將變量應(yīng)用到數(shù)學(xué)表達(dá)式中等操作。解析AngularJS表盡管AnguarJS會在運(yùn)行$gestAuS通過$parse這個(gè)內(nèi)部服務(wù)來進(jìn)行表達(dá)式的運(yùn)算,這個(gè)服務(wù)能夠當(dāng)前所處的作用域。這個(gè)過程允許我們定義在$scope上的Sr數(shù)據(jù)和函數(shù)。$parse服務(wù)注入到控制器中,然后調(diào)用它就可以實(shí)現(xiàn)手動(dòng)解析表達(dá)式。舉例來說,如果頁面上有expr示:ptle="Enteanexpesson"<h2>{{pae</d我們可以在yCotoler中給expr這個(gè)表達(dá)式設(shè)置個(gè)$atchm,tMap,,l)//用該表達(dá)式設(shè)置pavapaseFun=$pa;//cale=pa;}插要在字符串模板中做插值操作,需要在你的對象中注入ntepate服務(wù)。在下面的例子中,會將它注入 m,tM,)//我們同時(shí)擁 $scope和$nteplae服務(wù)的權(quán)$ntepottext(字符串 個(gè)包含字符插值標(biāo)記的字符串mustHaveExpression(布爾型):true,當(dāng)傳入的字符串中不含有表達(dá)式時(shí)會返回null。trustedContext(字符串)AguS$sce.getTrusted()方法進(jìn)行嚴(yán)格的上下文轉(zhuǎn)義。查看29.4節(jié)以獲得關(guān)于最后個(gè)參數(shù)的細(xì)節(jié)內(nèi)容$ntepate服務(wù)返 時(shí)進(jìn)行字符插值操作并將結(jié)果展示出來。"tpe="emaead<pe>{{pevewext}}</p</d為了確保每Body變化后更新previewText,我們需要設(shè)置$watch。3章會深入討$watch方法。完整起見,這里我們會$watch屬性中。在控制器中,我們設(shè)置了$w來監(jiān)視郵件正文的變化,并 Body屬性的值進(jìn)行字符插值后的結(jié)果賦值給peeet屬性m,tM,)//ad{f(bod)va te=$nteltebdcpevewext= {:;}實(shí)例:/oDeFuCAW/1/edt?htm,js,output現(xiàn)在,在{{pevewText}}內(nèi)部的文本中可以將{{to}}當(dāng)做如果需要在文本中使用不同于{{}}的符號來標(biāo)識表達(dá)式的開始和結(jié)束,可以在$iteroateProder中配置。用startSbol()方法可以修改標(biāo)識開始的符號。這個(gè)方法接受個(gè)參數(shù)。用eybo()方法可以修改標(biāo)識結(jié)束的符號。這個(gè)方法也接受個(gè)參數(shù):$interpolateProvider注入進(jìn)去。下面我們來創(chuàng)建4章會對服務(wù)進(jìn)行深入討論。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)在用自定義 符號取代默認(rèn)語法中的{{}}符號來請求插值文本,因此需要將HTML修改成用這個(gè)符號取代{{}}的版本,效果如圖6-1<d<dvd="emadto"tpe="emal"cle="Recpent"<textaeanglad"></texta</d<d<dvaPev<p pevew </p</d實(shí)例:/vuJEXI/1/edt第7 在HTML中的模板綁定符號{{}}內(nèi)通過符號來調(diào)用過濾器。例如,假設(shè)我們希望將字符串轉(zhuǎn)換成大寫,可以對字符串中的每個(gè)字符都單獨(dú)進(jìn){{{{nameuppecase在 pt代碼中使用oerae過濾器tt,ffunct$sc,$flte){eeA入冒號。例如,數(shù)值過濾器可以限制小數(shù)點(diǎn)后的位數(shù),在過濾器后寫上:2可以將2作為參數(shù)傳給過濾器: 顯示:6 {{9numbe2可以用符號作為分割符來同時(shí)使用多個(gè)過濾器,后面介紹自定義過濾器時(shí)就會看到相關(guān)的例子。我們先來介紹AnguarJS 個(gè)數(shù)值格式化為貨幣格式。用{{123 currency}}來將123轉(zhuǎn)化成貨幣格式。dateAguS中內(nèi)置了幾種日期格式,如果沒有指定使用任何格式,默認(rèn)會采用mediumDate格式,下面的例子中展示了這個(gè)格式。{{{{{{{{{{{{{{{{{{'md'dt'sot'''d'o'd'o'四位年份:四位年份:toda兩位年份:toda位年份:{{toda'''英文月份:英文月份:{{ '英文月份簡寫:{{ 'M'}}<!--Aug--數(shù)字月份:{{ '}}<!--08--年中的第幾個(gè)月份:{{ '}}<!--8--個(gè)月中的第幾天:{{ '英文星期:{{ '英文星期簡寫:{{ '}}<!--Thu--}}天中的第幾個(gè)小時(shí):{{toda}}<!--02小時(shí)制數(shù)字小時(shí):{{toda'}}<!--12上午或下午的第幾個(gè)小時(shí):{{toda''}}<!--12數(shù)字分鐘數(shù):數(shù)字分鐘數(shù):{{ e''}}<!--09--個(gè)小時(shí)中的第幾分鐘:{{ te''}}<!--9--數(shù)字秒數(shù):數(shù)字秒數(shù):{{ '分鐘內(nèi)的第幾秒:{{ '毫秒數(shù):{{ '上下午標(biāo)識:上下午標(biāo)識:{{ '四位時(shí)區(qū)標(biāo)識:{{ '下面是{{{{ ,{{ ,,'{{ 'fier過濾器可以從給定數(shù)組中選擇個(gè)子集,并將其生成個(gè)新數(shù)組返回。這個(gè)過濾器通常用來過濾需要進(jìn)行展示的元素。例如,在做客戶端搜索時(shí),可以從個(gè)數(shù)組中立刻過濾出所需的結(jié)果。這個(gè)過濾器的第個(gè)參數(shù)可以是字符串、對象或是個(gè)用來從數(shù)組中選擇元素的函數(shù)。下AuS$當(dāng)作鍵名。{{{{A''eneLk''''E''Pzza']flte''如果要過濾對象,可以使用上面提到的對象過濾器。例如,如果有個(gè)由eoe對象組成的數(shù)組,每個(gè)對象都含有他們最喜歡吃的食物{{{{:ACt':'nFanc,ote:Pzza':,Ct':'nFanc,o:' o:P也可以用自定義函數(shù)進(jìn)行過濾(在這個(gè)例子中函數(shù)定義在$scope上At]sCaptazed函數(shù)的功能是根據(jù)首字母是否為大寫返回true或falsecpe.sCaptalzed=functon(st{etunst[0]==sttUpe;第二個(gè)參數(shù)可以是以下三種情況之。 so過濾器可以將個(gè)JSON或JavaScrpt{{{{'':A',Ct':Fanc {"name":"Ari",}如果傳入的長度值大于作數(shù)組或字符串的長度,那么整個(gè)數(shù)組或字符串都會被返回例如,我們可以截取字符串的前三個(gè)字符:{{{{SanFancscos d lmt3{{San{{SanFancscos d lmt:6對數(shù)組也可以進(jìn)行同樣的操作。返回?cái)?shù)組的第{{{{] lmto:owecase{{{{"SanFancscos d e{{{{7 numbe2orderBy可以接受兩個(gè)參數(shù),第第個(gè)參數(shù)是用來確定數(shù)組排序方向的謂詞。下面分情況討論第個(gè)參數(shù)的類型。當(dāng)?shù)趥€(gè)參數(shù)是函數(shù)時(shí),該函數(shù)會被當(dāng)作待排序?qū)ο蟮膅etter方法。在排序表達(dá)式中使用數(shù)組元素作為謂詞。對于與表達(dá)式結(jié)果并不嚴(yán)格相等的每個(gè)元素,則使用第個(gè)謂詞。第{{{{:A:''m':',:,:' odeB'ne' ]{{{{:A:''m':',:,:' odeB'am':tue ]{{{{"SanFancscos d 自定義過濾mmf,p,{etunfuncton(nput)過濾器本質(zhì)上是個(gè)會把我們輸入的內(nèi)容當(dāng)作參數(shù)傳入進(jìn)去的函數(shù)。上面這個(gè)例子中,我們在調(diào)用過濾器時(shí)簡單地把input理??梢栽谶@個(gè)函數(shù)中做些錯(cuò)誤檢查:mfp,{etunfuncton(nput)//nput是我們傳入的字符串f(nput){e npulce(}{{gngelovesdogt' e 表要。<fo<fomnam=fo"nvllu>a </foAguS,我們不需要花太多額外的精力就可以輕松實(shí)現(xiàn)客戶端表單驗(yàn)證功能。雖然b應(yīng)用安全不能完全依賴客戶端驗(yàn)證,但客戶端驗(yàn)證可以提供表單狀態(tài)的實(shí)時(shí)反饋。要使用表單驗(yàn)證,首先要確保表單像上面的例子樣有個(gè)name下面 必填驗(yàn)證某個(gè)表單輸入是否已填寫,只要在輸入字段元素上添加HTML5標(biāo)記eured<<nputtpe="text"equed最小長 "最大長 "模式匹使用ng-pattern"/PATTERN/"電子郵驗(yàn)證輸入內(nèi)容是否是電子郵件,只要像下面這樣將pu的類型設(shè)置 即可ea驗(yàn)證輸入內(nèi)容是否是數(shù)字,將ut的類型設(shè)置為"e"驗(yàn)證輸入內(nèi)容是否是URL,將ut的類型設(shè)置為e 自定義在AnguarJS中自定義指令是非常容易的。鑒于目前還沒有介紹到指令的相關(guān)內(nèi)容,第10章再深入研究如何創(chuàng)建自定義驗(yàn)證。目前先來看下如何通過向后端服務(wù)器發(fā)送請求,并通過響應(yīng)的結(jié)果來將輸入字段設(shè)置為合法或不合法,以確保輸入字段中的內(nèi)容是唯的。在表單中控制如果在表單元素上綁定個(gè)ng-modelAuS$scope(注意,可以使用下面的格式這些屬性。.p未修改的.p修改過的.d合法的表如果當(dāng)前輸入字段的值有效,則這個(gè)布爾屬性值為.l不合法的如果當(dāng)前輸入字段的值無效,則這個(gè)布爾屬性值為.$l這是AnguarJS提供的另外個(gè)非常有用的屬性:$error對象。它包含當(dāng)前表單的所有驗(yàn)證內(nèi)容,以及它們是否合法的信息。用下面的語.e這些額外的屬性可應(yīng)用于單獨(dú)的輸入字段是有用的。類似的屬性同樣適用于整個(gè)表單。AnguarJS處理表單時(shí),會根據(jù)表單當(dāng)前的狀態(tài)添加些CSS類(例如當(dāng)前是合法的、未發(fā)生變化的,等等),這些CSS類名和前面介紹gpstnegdtgvaldgnvald當(dāng)某個(gè)字段中的輸入時(shí).ng-nld類會被添加到這個(gè)字段上。當(dāng)前例子中的站點(diǎn)將對應(yīng)的CSS樣式設(shè)置為utgvldbode:pxsold;}gvaldbode:pxsoldg;}當(dāng)用戶同控制器進(jìn)行交互,并且ngModelController$setViewValue()$parsers數(shù)組中的函數(shù)會以流水線的形式被逐個(gè)調(diào)用。第$parse$parse,以此類推。這些函數(shù)可以對輸入值進(jìn)行轉(zhuǎn)換,或者通過$setVaty()函數(shù)設(shè)置表單的$parsers數(shù)組是實(shí)現(xiàn)自定義驗(yàn)證的途徑之$parsers數(shù)組中入棧個(gè)新的函數(shù),這個(gè)函數(shù)會在驗(yàn)證鏈中被調(diào)用。每個(gè)$parser返回的值都會被傳入 個(gè)$parser中。當(dāng)不希望數(shù)據(jù)模型發(fā)生更新時(shí)返回udefedm)dectve'oeo,funct{etun,:,,,){fnMl)etu;ahVl){ =pasent(v;f(>=0&&<0)gMdl$setaldteo,te;etunvewVl;}elsele,etunundef;}}s當(dāng)綁定的ngModel$parsers$formatters流水線。$parsers數(shù)組可以修改表單的狀態(tài)類似$formatters中的函數(shù)也可以修改并格式化這些值。比起單純的驗(yàn)證目的,這些函數(shù)更常用來處理視圖中的可視變化。例如,假設(shè)我們要對某個(gè)值進(jìn)行格式化。通過$formatters數(shù)組可以在這個(gè)值上執(zhí)行過濾器:m)dectve'oeo,funct{etun,:,,,){fnMl)etuoeh{etun$flte'me;}組合實(shí)下面我們起創(chuàng)建個(gè)表單。表單中包括用戶的名字、郵件地址以及用戶名。開始之前,首先看下我們希望這個(gè)表單長成什么樣子,如圖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我們添加了個(gè)表單,這個(gè)表單有個(gè)名為name的輸入字段,并且這個(gè)輸入字段被ng-oel指令綁定到了$scope對象記給輸入字段添加name屬性。給輸入字段添加name屬性非常重要:這決定了 同時(shí),我們也設(shè)置了些驗(yàn)證。驗(yàn)證要求name字段的最小長度是3個(gè)字符,最大長度是20個(gè)字符(當(dāng)長度大于等于21時(shí)輸入會變?yōu)椴缓戏ǎW钔ㄟ^使用這些屬性,可以在表單未通過驗(yàn)證時(shí)控制展示或隱藏錯(cuò)誤列表。用$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)在整個(gè)表單都被包含進(jì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在最后個(gè)輸入字段中除了同前面相同的驗(yàn)證外,還添加了個(gè)自定義驗(yàn)證。這個(gè)自定義驗(yàn)證是用AnguarJSdu,{etun,:,,,t,f(!n)etu;:Su,:{'fl:att.ueUnque}tc$ldtnq,.sUnec$etldt'n',}當(dāng)表單內(nèi)容通過驗(yàn)證后,會向/apcheck/username發(fā)送個(gè)POSTngdsbld=sgnupfo$ld"n示例:/ePomUnI/5/edt之前提到過,表單本身會提供$iald和$ald 當(dāng)用戶試圖提交表單時(shí),你可以在作用域中捕獲到個(gè)smtt例如,修改下前面的例子,只在用戶提交表單時(shí)才顯示錯(cuò)誤信息。在ng-show指令中加入對表單是否進(jìn)行了提交的檢查(后面會實(shí)現(xiàn)這個(gè)功<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)在,僅當(dāng)signup_form.submittedtrue時(shí),容納錯(cuò)誤信息的div才會展示出來。在signupForm操作中實(shí)現(xiàn)這個(gè)行為,如下所示:tmcsgnupFom=functon()sl//}elsecsgnupfomtted=t;}如果用戶試圖在有輸入的情況下提交表單,我們現(xiàn)在可以捕獲到這個(gè)行為并展示合適的錯(cuò)誤信息。示例:/ePomUnI/6/edt。在失焦后顯如果想保留實(shí)時(shí)錯(cuò)誤提示的體驗(yàn),可以在用戶從某個(gè)輸入字段失焦后提示錯(cuò)誤信息(例如用戶已經(jīng)不在某個(gè)特定的輸入字段中時(shí))這個(gè)效果,需要實(shí)現(xiàn)個(gè)不是很復(fù)雜的指令,并向表單中添加個(gè)新的變量。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)的行為,添加了個(gè)名為ng-focused的類,并將$focused的值設(shè)置為true<d<dvcl"eod$l>示例:/ePomUnI/7/edt也可以在ngModel控制器中使$isEmpty()方法來判斷輸入字段是否為空。當(dāng)輸入字段為空這個(gè)方返true,反之如果不為空則返false。眾所周知,表單和驗(yàn)證是Anguar中復(fù)雜的組件之。然而,在Anguar1.3中我們有個(gè)有用的升級用于管理表單驗(yàn)證的錯(cuò)誤消息,叫作ngMessages。讓我們來看個(gè)“老方式”的示例并將它與ngMessages進(jìn)行比較。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ì)上這功能會檢查錯(cuò)誤對象的狀態(tài)發(fā)生了變化。此外,我們還得到了站點(diǎn)中每個(gè)表單需要的很多額外的和重復(fù)的標(biāo)記。這顯然不是個(gè)理想的安裝ngMessages很簡單,因?yàn)樗淮虬闪藗€(gè)Anguar模塊。首先這個(gè)模塊$$bowel saveglacaacm,;現(xiàn)在,我們已經(jīng)安裝了ngMessagesng-show指令,然后使用ngMessages的個(gè)更簡潔的實(shí)現(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有時(shí),你可能希望為不同的字段自定義錯(cuò)誤信息。沒問題,你可以在這個(gè)指令內(nèi)簡單的插入個(gè)自定義錯(cuò)誤信息。由于ngMessages涉esem tes/eo>></d此外,甚至還可以為自定義驗(yàn)證創(chuàng)建自定義消息??梢酝ㄟ^修改模型的$parsers鏈做到這點(diǎn)。例如,比方說我們想要?jiǎng)?chuàng)建個(gè)自定義驗(yàn)證器驗(yàn)證用戶名在個(gè)表單中是否有效: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在這中用法中,我們檢查了錯(cuò)誤信息的自定義屬性。為了添加自定義錯(cuò)誤消息,會把它們應(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)我們對這個(gè)最基本的WebHTML文HTML節(jié)HTMLHTML元HTML元素由個(gè)開始和個(gè)結(jié)束組成HTML用來標(biāo)記元素的開始和結(jié)束。本身用尖括號來 "aue的鍵值對設(shè)置它們,或者只設(shè)置鍵 ,它可以創(chuàng)建從個(gè)頁面到另個(gè)頁面的:很多和超樣,會有很多特殊的屬性,這些屬性就好比的 的href屬性會激活該 <a<ah "lckmetogo l>默認(rèn)情況下超是藍(lán)色且有下劃線的,而按鈕在瀏覽器中看起來 超知道當(dāng)自己的hre屬性被設(shè)置 之后,如果用戶點(diǎn)擊這個(gè)超,它應(yīng)該修改地址欄的URL并加載 最后,兩個(gè)在設(shè)置了title屬性時(shí)則有相同的行為:當(dāng)用戶將鼠標(biāo)懸停在元素上時(shí)會出現(xiàn)個(gè)提示框<a<ah"tllcklckmetogoll>總地來說,瀏覽器會渲染HTML元素的樣式和行為,這個(gè)能力是Web強(qiáng)大功能的基礎(chǔ)之任何個(gè)瀏覽器廠商,無論是Googe或Mcrosoft都盡量遵循同樣的HTML標(biāo)準(zhǔn),以此來保證Web編程在跨設(shè)備和操作系統(tǒng)時(shí)的致性。老版本的IE瀏覽器并沒有遵循標(biāo)準(zhǔn)的HTML定義,因此我們需要些技巧才能讓其正常工作。內(nèi)容請查看第30章。近來出現(xiàn)了很多新的HTML,它們是HTML5標(biāo)準(zhǔn)的部分。例 可以定義個(gè)、剪輯或流<v<vdeoh . 指令:自定義HTML元素和屬基于我們對HTML元素的理解,指令本質(zhì)上就是AnguarJS擴(kuò)展具有自定義功能的HTML元素的途徑。例如,我們可以創(chuàng)建個(gè)自定義元素,它實(shí) >的功能并且能在所有瀏覽器中工作:<m<mbettevdeomhef="</mbettev.cgofv>注意,這個(gè)自定義元素使用了特殊的開始和閉合mybetter- 為了讓這個(gè)更有用,可以將瀏覽器默認(rèn)的 <v<vdeomgofv>Canstlltakechden</v正如我們看到的那樣,指令可以和其他指令或?qū)傩越M合 為了有效了解如何將個(gè)個(gè)小組件組合成個(gè)復(fù)雜的系統(tǒng),首先要了解更基礎(chǔ)的內(nèi)容。接下來幾節(jié)的目標(biāo)就是幫助你了解這些基礎(chǔ)內(nèi)容,我們開始HTML引當(dāng)瀏覽器加載個(gè)包含AnguarJS應(yīng)用的HTML時(shí),我們只需要小段很簡單的代碼就能夠啟動(dòng)AnguarJS應(yīng)用(前面的章節(jié)介紹過相關(guān)內(nèi)中要用內(nèi)置指令ng-app標(biāo)記出應(yīng)用的根節(jié)點(diǎn)。這個(gè)指令需要以屬性的形式來使用,因此可以將它寫到任何位置,但是寫到<html>的開始上是最常規(guī)的做法:內(nèi)置指令是打包在AnguarJS內(nèi)部的指令。所有內(nèi)置指令 <<lngm>現(xiàn)在,在HTML元素中可以使用所有內(nèi)置或自定義指令了。同時(shí),基于JavaScrpt的原型繼承機(jī)制,任何在這個(gè)根元素內(nèi)部的指令只要能夠由于指令的生命周期非常復(fù)雜,會有專門的章節(jié)來介紹。在那部分內(nèi)容中還會討論指令中哪些方法是可以作用域的,以及作用域是如何在我們的 個(gè)指學(xué)習(xí)指令最快的途徑就是親自使用它,讓我們來創(chuàng)建個(gè)自定義指令。的HTML元素,后面我們會用到它<m<mdectve></mdect假設(shè)我們已經(jīng)創(chuàng)建了個(gè)完整的HTML文檔,其中包含了AnguarJS,并且DOM中已經(jīng)用ng-app指令標(biāo)識出了應(yīng)用的根元素,當(dāng)AnguarJS編mDiectiem)dectvmDect,funct{etun, te:ahlckmetogo 通過AnguarJS模塊API中的diecte()方法,我們可以通過傳入個(gè)字符串和個(gè)函數(shù)來個(gè)新指令。其中字符串是這個(gè)指令的名字,指令名應(yīng)該是駝峰命名風(fēng)格的,函數(shù)應(yīng)該返回個(gè)對象。駝峰命名風(fēng)格用來將個(gè)短語寫在個(gè)單詞中,除了第個(gè)單詞外其他單詞首字母大寫,中間不加空格。例如,bumpy在我們的例子中,在HTML里使用mdirecte 指令,因此指令定義必須以Dete為名字diecte()為了盡快掌握簡單的屬性定義,我們只用了restrict和mte兩個(gè)設(shè)置項(xiàng)來定義指令注意,代碼和你在文本編輯器中輸入的沒有區(qū)別,同時(shí)其中并沒有個(gè)。但的確屏幕上有個(gè)寫著“CckHere“,這是怎么回事?為了分析這個(gè)現(xiàn)象,,在彈出菜單中選擇InspectEement,如圖8-3所示。圖8-3InspectE默認(rèn)情況下,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)建),因?yàn)槭聦?shí)上指令并不需要?jiǎng)?chuàng)建個(gè)新的自定義元素指令本質(zhì)上是在HTML中通過元素、屬性、類或注釋來添加功能。<m<mdect<dvmdect<dvcl="mdect為了AguS能夠調(diào)用我們的指令,需要修改指令定義中的restrict設(shè)置。這個(gè)設(shè)置告AuS在編譯用哪種格式來匹配指令定義。我們可以指定個(gè)或多個(gè)格式。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章)來解決這個(gè)問題,但這樣做的就是,當(dāng)疏忽了致性時(shí)會導(dǎo)致額外的問題。值得注意的個(gè)例外是,擴(kuò)展內(nèi)L,例如AuS重載<a><form>和<input>。這些場景不會導(dǎo)致瀏覽器的兼容性問題,因?yàn)樗鼈儽旧砭褪菫g覽器所支持的。表達(dá)<h<hngnt="geet' hegeetngs:{{geetng</h 'ood賦值給內(nèi)置指令ng-it。在表達(dá)式中,get屬性的值設(shè)置為 Word然后計(jì)算花括號內(nèi)的{{geetng}}這個(gè)表達(dá)式的值。這兩種情況都會在當(dāng)前作用域中計(jì)算個(gè)普通的JavaScrpt表達(dá)式。根據(jù)這個(gè)表達(dá)式放置的位置不同,當(dāng)前作用域可以是AnguarJS在應(yīng)用啟動(dòng)用表達(dá)式來指我們知道指令時(shí)既可以使用表達(dá)式,也可以不使用表達(dá)式。下面回 下幾種合法的表達(dá)式<m<mdectveAtbte"somexpess</mdect<dvmdectv"smExpess</d<dvls="mdectvexpess</d dectve:mdectvesomeExpess 這里有個(gè)值得注意的問題,賦值給指令的表達(dá)式會在哪個(gè)環(huán)境中運(yùn)行?要回答這個(gè)問題,首先要了解個(gè)復(fù)雜但非常重要的概念,就是當(dāng)前作用當(dāng)前作用域首先快速了 下由DOM通過內(nèi)置指令ng-cotole提供的作用域。這個(gè)指令的作用是在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)用時(shí)行為和ng-controller類似。我們在構(gòu)造自定義指令時(shí)也可以創(chuàng)建新的子作用域。向指令中傳遞回顧下如何定義指令:m,dectvmDect,funct{etun, ce:t, te:ah"lckmetogo'} 'ah ">lckmetogoto'如果不L和文本混在指令內(nèi)部,可以為其他使用我們指令的人提供更好的體驗(yàn)。我們的目標(biāo)是關(guān)注指令的公共接口,就像其他任何程語言樣。實(shí)際上,應(yīng)該將上面的模板轉(zhuǎn)換成可以接受兩個(gè)變量的形式:個(gè)變量L,另個(gè)是文本: te:ahef="{{mUl}}">{{mLnkext'在主HTML文檔中,可以給指令添加yUrl和 nText兩個(gè)屬性,這兩個(gè)參數(shù)會成為指令內(nèi)部作用域的屬性<d<dvmdectvemu""mlnktxt"Clckmetogo </d重新加載頁面,注意指令的部分已經(jīng)被模板代替,但是的href屬性是空的,并且尖括號內(nèi)也沒有文本,如圖8-6所示盡管簡單,共享狀態(tài)會導(dǎo)致很多其他問題。如果控制器被移除,或者在控制器的作用域中也定義了個(gè)叫yUrl的屬性,我們就被迫要修改代同之前在當(dāng)前作用域介紹中介紹的繼承作用域(子作用域)不同,作用域同當(dāng)前DOM的作用域是完全分隔開的。為了給這個(gè)新的對象設(shè)置屬性,我們需要顯式地通過屬性傳遞數(shù)據(jù),同在JavaScrpt或Ruby中給方法傳遞參數(shù)類似。當(dāng)用如下代碼將指令的作用域設(shè)置 }實(shí)際上創(chuàng)造的是作用域。本質(zhì)上,意味著指令有了個(gè)屬于自己的$scope對象,這個(gè)對象只能在指令的方法中或指令的模板字符串中使 te:d</d,//P}}目前為止,我們直忽略了個(gè)細(xì)節(jié)。實(shí)際上不能像上面的例子那樣,在作用域?qū)ο髢?nèi)部直接設(shè)置smerpert//s'}<d<dvmdectsomepopet"Popetwth@bnd</dsomeProperty值設(shè)置為@AguSD中some-property屬性的值給新作用域?qū)ο笾械膕omeProperty屬性:'}注意,默認(rèn)情況下smerpert在DOM中的映射是ome-propertyt}在這個(gè)例子中,被綁定的屬性名是omeattr而不是omeproperty<d<dvmdectsomeatt"Popetwth@bnd</d現(xiàn)在,當(dāng)我們在指令模板或控制器中(之前的例子這樣做過 smerpert時(shí),會得到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默認(rèn)情況下約定DOM屬性和JavaScrpt中對象屬性的名字是樣的(除非對象的屬性名采用的是駝峰式寫法)tmLnkext:''}上面的作用域中的內(nèi)容是:將指令的私有屬$scope.myUrl同Dsome-attr屬性的值綁定起來。這個(gè)值既可以是硬編碼的也可Some-attr"{{expression}}"在DOM中要用omeattr代替my-<d<dvmdect"mlnktxt"Clckmetogo "</d更 <d<dvmdect'</d''在此之上,我們來看看如何創(chuàng) 注意在輸入 上使用了內(nèi)置指令ng-ode。這個(gè)指令可以將輸入文本同$scope上的mr屬性進(jìn)行綁定m<dvmdectmlnktxt"Clckmetogo </d這段代碼是可以工作的,但如果文本輸入字段移到指令內(nèi)部并在另個(gè)指令中進(jìn)行綁定,就無法正常工作了<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)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論