Java零基礎(chǔ)入門教程-AngulaJs開發(fā)技巧匯總

一、整體架構(gòu)篇
1、按功能模塊劃分而不是MVC結(jié)構(gòu)
? ? ? ?盡管有些文章上是推薦MVC結(jié)構(gòu),但是個(gè)人認(rèn)為這種方法對小項(xiàng)目還可以接受。如果大項(xiàng)目的話,就會(huì)顯得很臃腫,而且每個(gè)js文件都只有一些代碼。這樣還不如直接按功能模塊,將公共的方法抽取到一個(gè)公共模塊當(dāng)中,每個(gè)功能模塊就只對應(yīng)一個(gè)js文件,然后在里面寫Controller/service/config等等。
2、模塊化、公共化
? ? ? ?對于每一個(gè)頁面可能都會(huì)用到的一些公共方法,如果get/post的ajax請求,就可以封裝在一個(gè)service里面,然后這個(gè)service放在公共js文件里,其實(shí)頁面有需要調(diào)用,只需要引入此模塊,注入此service.
3、控制Controller層的大小?
? ? ? 因?yàn)镃ontroller不是單例的,所以每次訪問時(shí)實(shí)例一個(gè),這樣會(huì)很耗費(fèi)性能。所以建議是只在此頁面上應(yīng)用的一些公共變量或公共方法可以抽取出來,放在Serivce或者其它。
4、盡量使用AngularJs原生自帶的指令、函數(shù)等
? ? ?如果AngularJs自帶的指令或函數(shù)等不能滿足你的要求,個(gè)人v建議是yi自己來寫指令,包括配置等。自己寫一方面你可以很方便進(jìn)行擴(kuò)展,另一方面維護(hù)性也會(huì)比較好。建議不要用太多的第三方插件,能用原生就用原生的,不能就自己寫,實(shí)現(xiàn)不行才考慮第三方AngularJs相關(guān)插件。
5、拋棄Jquery
? ? ? ?經(jīng)??吹侥欠N引入了AngularJs而又引jQuery文件,然后代碼里頭scope和$('#....')到處飛。這樣整個(gè)js文件就非常亂,你根本就很難來進(jìn)行調(diào)試,而且后面維護(hù)的人難度也會(huì)加大。完成不符合AngularJs數(shù)據(jù)驅(qū)動(dòng)的思想,使用了AngularJs,就不要再想Jquery。NO!
6、Anuglar UI bootstap推薦使用
? ? ? ?使用Anuglar UI bootstap就相當(dāng)于只要引入bootstarp的CSS文件,angularjs文件,還有UI bootstap的js文件,你就可以設(shè)計(jì)出非常好看的界面效果。Anuglar UI bootstap就相當(dāng)于是一個(gè)將bootstarp.js文件用Angular指令的方法重寫了。然后你只需要引入bootstarp.css文件即可。
7、數(shù)據(jù)驅(qū)動(dòng)而不是Dom設(shè)計(jì)
? ? ? 不要一來就使用類似Jquey的思想,如我要給這個(gè)按鈕加什么事件。獲取什么值。而應(yīng)該是想這個(gè)按鈕綁定了什么數(shù)據(jù),我應(yīng)該怎么去變化這個(gè)數(shù)據(jù)即可。不要想著自己去改變Dom,而是應(yīng)該想著怎么去對數(shù)據(jù)進(jìn)行增刪改查,綁定到對應(yīng)的數(shù)據(jù)。Angulatjs自然會(huì)去幫你重新更新Dom元素。
8、使用ng-inspector來調(diào)試
? ? ?其實(shí)說是調(diào)試,在Angularjs里準(zhǔn)確說應(yīng)該是看數(shù)據(jù)的變化。這個(gè)是一個(gè)瀏覽器插件,可以實(shí)時(shí)顯示當(dāng)前頁面是否使用Anguarljs,以及它當(dāng)前頁面所有的綁定的數(shù)據(jù)。非常直觀
二、性能使用篇
1、盡量少用$watch
? ? ? ?$watch會(huì)非常耗費(fèi)性能,建議使用ng-change,ng-select來替換。
2、使用ng-bind
? ? ? ?不使用{{}},而是ng-bind。一方面可以避免數(shù)據(jù)未加載完全時(shí)頁面的閃爍,另一方面g-bind性能也更加好。
3、$rootScope不要綁定太多數(shù)據(jù)
? ? ? rootScope就相當(dāng)是全局變量,綁定多了,不僅可以會(huì)和子scope變量沖突,也會(huì)引起性能的下降。
4、頁面內(nèi)盡量少用filters
? ? ? ?當(dāng)在頁面內(nèi)的模型后面增加filter時(shí),這個(gè)會(huì)造成當(dāng)前模型在$digest里運(yùn)行兩次,造成不必要的性能浪費(fèi).第一次在$$watchers檢測任務(wù)改變時(shí);第二次發(fā)生在模型值修改時(shí),所以盡量少用內(nèi)聯(lián)時(shí)的過濾器語法,像下面這樣的非常影響頁面性能。
5、注意 ng-if/ng-show的使用
? ? ? ? ng-if是移除dom。而ng-show是隱藏dom,所以個(gè)人建議是對于大對象dom,建議使用ng-show,對應(yīng)小對象dom,建議使用ng-if;
6、Scope不超過2000個(gè)
? ? ? ?有一些文章上說Scope超過2000個(gè)后,AngualrJs性能會(huì)急速下降,這個(gè)觀點(diǎn)個(gè)人沒做過驗(yàn)證,不敢做擔(dān)保。
7、 過濾器(Filters)
? ? ? ?要盡量避免使用過濾器。他們會(huì)在每個(gè)更新周期運(yùn)行兩次,每當(dāng)發(fā)生任何改變時(shí)運(yùn)行一次,另一次是收集更深層次的改變時(shí)觸發(fā)。所以不要直接從內(nèi)部列表中移除對象,使用CSS控制即可。(注* 用添加CSS類名去隱掉他們)渲染時(shí)的 $index 值并不是真正的數(shù)組索引值,它豪無價(jià)值。但是排好序的數(shù)組索引,無法讓你遍歷到所有列表中的域。
8、更新 ng-repeat
? ? ? ? 當(dāng)使用ng-repeat時(shí)要盡量避免對全局列表的刷新。ng-repeat會(huì)產(chǎn)生一個(gè)$$hashkey屬性和一系統(tǒng)唯一的項(xiàng)。這意味著當(dāng)你調(diào)用 scope.listBoundToNgRepeat = serverFetch() 時(shí)會(huì)引起對整個(gè)列表的重新刷新。會(huì)通知執(zhí)行所有的watchers并觸發(fā)每一個(gè)元素,這是非常消耗性能的。這里有兩種解決方案。一種是維護(hù)兩個(gè)集合,和帶有過慮器(filter)的ng-repeat(基本上需要自定義同步邏輯,因此算法更復(fù)雜,可維護(hù)性更差),另一種方案是使用track by去指定你自己的key(Angular 1.2 開始支持,只需要很少的同步邏輯)。?
9、$digest() 和 $apply()
? ? ? scope.$apply 是一個(gè)強(qiáng)大的工具,可以讓你向Angular引入外部的值。本質(zhì)上它會(huì)觸發(fā)Angular的所有事件(例如ng-click)。問題是scope.$apply會(huì)從根域$rootScope開始,遍歷所有的域鏈,觸發(fā)每一個(gè)域。scope.$digest只會(huì)執(zhí)行指定域及其相關(guān)的域。兩種性能差異不言自明。折中的方案是,不觸發(fā)任何域等到下一個(gè)更新周期再更新。
10、 $on, $broadcast 和 $emit
? ? ? ?像$watch一樣,他們都是一些很慢的事件,(有可能)遍歷整個(gè)作用域。他們可能像GOTO一樣,讓你的程序無法調(diào)試。不過幸運(yùn)地是像$watch一樣,他們都可以在完全不需要的時(shí)侯解綁。比如在 $on('$destroy')中。
11、 $destroy
? ? ? ? 像前面提到的那樣,你應(yīng)該在$on('$destroy')中解綁你所有的事件偵聽器,取消任何$timeout的實(shí)例,或者任何其它異步執(zhí)行的交互。這不僅僅是確保安全。還可以讓你的域更快地被垃圾回收。不這樣做,他們會(huì)一直在后臺(tái)運(yùn)行。直接你清空CPU和RAM。另外,解綁DOM上的事件偵聽器也非常重要,不這樣做很可能在老式瀏覽器中引起內(nèi)存泄露。
12、 $evalAsync
? ? ? ?scope.$evalAsync是一個(gè)強(qiáng)大的工具。它可以在當(dāng)前域中執(zhí)行,并不觸發(fā)域的更新。evalAsync可以極大地提高你網(wǎng)頁的性能。
13、編繹周期
? ? ? ? 指令(Directive)的compile函數(shù)是在域被附加前操作DOM的完美功能(比如說綁定事件)。一個(gè)很重要的性能方面是,傳入compile函數(shù)的元素和屬性以原始html模板呈現(xiàn)。只會(huì)被運(yùn)行一次,接下來會(huì)直接使用。另外一個(gè)重要的點(diǎn)是prelink和postlink的區(qū)別。prelink從外向內(nèi)執(zhí)行。postlinks從內(nèi)向外執(zhí)行。prelink性能稍好一些,因?yàn)樗粫?huì)產(chǎn)生第二次更新周期。但是這時(shí)子元素的DOM還未被創(chuàng)建。
14、ng-repeat多個(gè)字段排序的寫法
? ? ? 使用orderBy過濾器,第一個(gè)參數(shù)是一個(gè)數(shù)組,表示依次按數(shù)組中的屬性值進(jìn)行排序(若按第一項(xiàng)比較的值相等,再按第二項(xiàng)比較),第二個(gè)參數(shù)是正序還是倒序(默認(rèn)是正序)。ng-repeat="groupUser in groupUsers | orderBy:['isOwner','isAdmin']:true"
15、ng-include引入HTML片段
? ? ? ?使用ng-include,第一個(gè)參數(shù)是頁面的相對地址的字符串。應(yīng)該注意,是一個(gè)字符串,不是ng-expression,所以不要忘了加單引號(hào),否則會(huì)發(fā)現(xiàn)怎么都引不進(jìn)這個(gè)HTML片段。<div ng-include="'msgs.html'"></div>
16、 關(guān)于ng-bind-html
? ? ? ? 通常情況下為html元素綁定數(shù)據(jù),有ng-bind就夠了,但一些情境下需要綁定的不是一般的數(shù)據(jù),而是html.那么ng-bind就不夠用了,需要使用ng-bind-html,它會(huì)將內(nèi)容作為html格式輸出.比如想輸出帶有class的html,那么就使用ng-bind-html,而且還需要ngSanitize的配合,需要引入相應(yīng)的文件.