AngularJs項目實踐總結

    今年3月接觸AngularJs,而且在6月的項目中開始應用,從踩坑到填坑花了很多時間,根據項目中的實際應用狀況總結了一些經驗,以下:javascript

一.UI控件選擇html

    Angularjs是不缺控件的,Github裏現成的控件很是豐富,基本上足以應付一個普通管理系統中常見的控件需求。可是控件的豐富會帶來選擇的困難。選擇控件要知足幾個原則:
原則1:符合業務場景
原則2:控件持續更新
原則3:知足性能要求前端

     舉幾個例子。首先是上傳附件的控件。項目中要用到附件上傳,谷歌上搜到了三個控件,分別是
https://github.com/leon/angular-upload
https://github.com/danialfarid/ng-file-upload
https://github.com/nervgh/angular-file-uploadvue

    由於項目須要兼容IE9,就重點關注了這三個控件對瀏覽器的兼容性。第一個控件沒有任何說明,第二個控件支持IE9,可是前提是要安裝flash,第三個控件支持IE8和9,可是隻支持部分功能。從瀏覽器兼容性的角度考慮,最終選擇了控件三。java

     再舉一個例子,下拉框控件。html原生的select功能比較單一,而且option的樣式很難修改,在前端各個框架所用的下拉框基本上都是從新實現的。Angularjs也不例外。項目中剛開始選用了ui-select2。後來在ui-select2的介紹中看到這句話:
This directive is now obsolete. A new initiative, more active, and 100% angular is available at https://github.com/angular-ui/ui-select.
發現ui-select2已經有3年沒有更新了,果斷棄坑選用ui-select。git

    最後談談原則3,仍是說ui-select吧,它雖然是ui-select2的改進版,可是性能上是存在問題的,根據stackoverflow上的問答,一個ui-select裏包含過多選擇項或者一個頁面包含過多ui-select控件時,性能有明顯下降。由於這一點,曾考慮用其餘控件替換掉ui-select,不過項目中並不存在大數據量和過多控件的狀況,最後仍然保留了它。在知足原則1和2和前提下,只能儘可能知足原則3。github

   一個新項目在開發前,最好能根據需求調研可能用到的UI控件,並嘗試寫一些demo,尤爲對複雜的UI控件。好比ui-grid,有太多的指令和api,花費在閱讀文檔和官方實例代碼的時間也是一筆不小的投入。api

二.自定義指令數組

    自定義的指令要加命名空間(前綴),防止全局指令名污染,就像javascript中防止全局變量污染同樣。在項目中,某個頁面出現了這樣的錯誤:
Error: [$compile:multidir] Multiple directives [refresh, uiSelectChoices] asking for template on: <ui-select-choices repeat="searchRes in searchRes" refresh="searchMedia($select)">瀏覽器

   可是新建一個測試用的解決方案,ui-select倒是正常的。幾經搜索,後來才發如今項目公共的directive裏定義了一個叫refresh的指令,它和ui-select的refresh指令重名了。
解決辦法很簡單,重命名自定義的refresh指令。

三.頁面防抖動

   在頁面初始化的時候,用戶可能會先看到 {{ }},而後閃爍一下才出現真正的內容。這是由於Angularjs會在dom加載完後纔會解析{{ }}中的內容,在這以前,{{ }}不是Angularjs的插值表達式,而是文本。
解決辦法:
1. 在要顯示的內容上使用 ng-cloak指令,而且添加以下樣式

<style> [ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak, .x-ng-cloak { display: none !important;
}
</style>

2. 使用 ng-bind 替代 {{ }}

四.模塊化思惟

    Angularjs推薦模塊化開發,module的本意便是模塊化,可是在Angularjs 1.X中,module更多體現出來的是一個「命名空間」的概念,而不是真正意義上的模塊化。好比A模塊依賴B模塊,B模塊應該是一個獨立的東西,可是被A引用以後,A、B模塊中的指令,服務,控制器所有混在了一塊兒,使用指令、控制器時甚至不須要指定是哪一個模塊中的指令和控制器。在Angularjs2中已經拋棄了module,ES6也引入了javascript底層的模塊化。在模塊化這方面,沒必要按照Angularjs 1.X鋪好的路走。

   在項目中,咱們的作法是,整個單頁面應用是一個module,每一個頁面對應一個controller和view,公共的功能寫在service中(這點還須要改進,呵呵)。
    controller的定位應該是一個完整且儘量小的功能模塊。好比一個列表頁,點擊某條記錄後彈窗顯示該記錄的詳細信息,那麼列表頁寫一個controller,詳細頁寫另外一個controller。controller之間是低耦合的,若是有必定的依賴關係,使用事件廣播與接收進行通信($emit, $broadcast, $on)。controller是不可複用的。
    公共的邏輯寫在service中,而且按功能分類,知足單一職責。使用時用依賴注入。避免寫成全局的公共方法。

五.懶加載

    單頁面應用若是體量較小,徹底不須要懶加載,把全部腳本打包壓縮在一塊兒是更好的解決方案。可是體量較大,加載的腳本又多又大,就須要考慮懶加載的方式了。按需加載文件,而不是一次性加載整個應用所須要的所有文件。懶加載的方式推薦用ocLazyLoad,而不要用requireJs。由於requireJs只能加載文件,沒法註冊module,controller,directive,而ocLazyLoad不但能夠加載文件,也能夠完成註冊。配合ui-route的路由管理,實現懶加載很是方便。

六.性能

    Angularjs採用髒檢測的方式來檢查對象的變化,與其餘框架相比——好比同爲MVVM模式的vue.js或者使用了虛擬dom的React——Angularjs的性能並不出衆。可是,開發一個單頁面應用或者一個管理系統,性能徹底不是瓶頸。形成Angularjs性能下降的關鍵因素每每是添加了太多的watcher,超過2000(經驗數值)個watcher時,會明顯下降性能。因此提升性能的基本方法就是儘可能減小watcher數量,好比使用ng-repeat時限制數組的長度並使用track by,以及一次性數據綁定{{::x}}

七.安全

    AngularJs自己不容許不安全的代碼,好比controller中定義一段帶有html標籤的字符串:
$scope.html="<p>text</p>";
在頁面上顯示的是原始的字符串,而不是一個段落。這是Angularjs自身的防XSS攻擊機制。除此另外,做爲開發人員,應該注意不要在模版中動態簽入用戶輸入的數據。固然,若是須要顯示html編碼後的內容,也是能夠的,使用$sanitize或$sce服務便可。$sanitize會按照Angularjs自身設置的白名單來淨化html,$sce服務包含有$sce.trustAs,$sce.trustAsHtml,$sce.trustAsUrl,$sce.trustAsResourceUrl,$sce.trustAsJs等方法,用於編碼可信任的html標籤。

 總結:Angularjs做爲當前流行的MVVM框架,開發管理類的CRUD系統真的太合適了。Javascript中一切皆對象,而在Angularjs中能夠說一切皆數據,以數據驅動的方式解決dom的更新,提高很多開發效率。本次項目只是Angularjs的首次應用,只接觸到了框架自己的部分功能,但願之後能有更多項目應用Angularjs。另外,Angularjs2已經在9月15日正式發佈了,也許某天能夠用Angularjs2來開發新的項目~

相關文章
相關標籤/搜索