實在太久沒寫 AngularJS 學到的東西...因為最近要學的東西實在太多 XD
這篇主要是要記錄與說明所學到 AngularJS 在載入頁面時的運作流程
與因應流程改善使用者體驗的 ng-cloak 這個 directive
一樣是屬於基本的初學者範圍
首先AngularJS 運作的流程如下 :
1. 載入 HTML文件,觸發相關的檔案請求 (js、css...等)
打廣告 : 想要優化這些請求加快網站速度可以參考上次寫的這篇
根據 Google PageSpeed Insights 為行動網站進行效能調校
2. 文件被載入後,AngularJS 啟動,並搜尋 ng-app 這個 directive
3. 找到 ng-app 後,會載入指定的模組,如果你有指定的話
ex:
<body ng-app="mymodule">
</body>
4. 接下來會在 ng-app 這個根元素中的DOM子元素裡尋找其他的 directives 或是綁定的陳述句 {{ }}
5. 每當遇到 ng-controller 或是 ng-repeat,會建立 AngularJS 所稱的 scope
scope 會決定每個DOM元素的存取函數與變數,指的就是你 controller 裡面傳入的那個 scope
而在遇到 ng-repeat 的時候 AngularJS 也會自動建立一個 note 的變數 (跟controller 內的變數無關)
用來存放陣列中的每個項目值,為了確保每個 ng-repeat 都有自己的內容值
所以每個 ng-repeat 都會有自己的 note 變數
6. 然後 AngularJS 會針對存取的變數增加監視器 (watcher) 與監聽器 (listener)
用來記錄這些變數的內容值,當值一改變 AngularJS 就會更新至 UI
7. 接下來就只會在特定的事件上檢查UI內容的更新 ex: 滑鼠點擊或鍵盤輸入
以上就是 AngularJS 載入頁面的步驟與所做的事
接下來要說明的,就是關於頁面載入時的資料綁定所造成的使用者體驗問題
資料綁定的方式基本上有下面兩種 :
1. 使用 ng-bind
2. 使用兩個大括號來表示 ex : {{ ctrl.Message }}
但剛剛上面有講到 AngularJS 的載入步驟,在第二步 AngularJS 動作前,文件必須先被載入完成才行
這就會造成如果你是使用 {{ ctrl.Message }} 來做為綁定的話
在一開始文件載入完成前,使用者在網頁上都會看到 {{ ctrl.Message }} 這段字
雖然時間很短暫,但直到 AngularJS 被啟動後才會真正的完成置換動作並繫結資料
所以資料綁定就盡量使用 ng-bind 好處會比較多
如果想要避免使用 {{ ctrl.Message }} 時的視覺暫留問題的話
AngularJS 有提供了 ng-cloak 這個 directive 來避免這個問題
ng-cloak 的作用是用來在 AngularJS 啟動與完成載入的這段時間內,隱藏不適合讓使用者看到的區塊
例如這樣 :
<div ng-cloak>{{ ctrl.Message }}</div>
這樣使用者就不會看到 {{ ctrl.Message }} 的殘影
但這前提必須是在 angular.js 函式庫放在網頁最頂端的情況下
因為 ng-cloak 之所以會有作用,其實是angular.js 將下面這段樣式套用到頁面上的緣故
請看官網 : https://docs.angularjs.org/api/ng/directive/ngCloak
[ng\:cloak],[ng-cloak],[data-ng-cloak],[x-ng-cloak],.ng-cloak,.x-ng-cloak {display: none !important;}
也可以看一下 angular.js 的核心程式最末端,就可以發現 angularjs.js 預設就會添加這段樣式了
他把它 display:none了,所以當然就不會顯示
然後在 AngularJS 完成載入之後,就會把相關元素的 ng-cloak 移除,然後使用者就可以看到資料
所以如果是放在最末端,在 AngularJS 完成載入之前都不會套用樣式,寫了等於白寫
但如果是放在最頂端可能還是有被使用者看到的問題,因為可能DOM載入的比 js 動態寫入的樣式宣染的快
雖然一般來說網頁載入碰到 js 應該會有阻塞行為才對,會等待 js 載入
但最快且最好的辦法則是將下面這段 css 當作自訂 css 的一部分
[ng\:cloak],[ng-cloak],[data-ng-cloak],[x-ng-cloak],.ng-cloak,.x-ng-cloak {display: none !important;}
這樣就可以在 HTML 內容開始顯示之前,讓樣式直接被載入了
加入樣式之後,除了使用 ng-cloak 這個 directive 之外
而且也可以用 <div class="ng-cloak">{{ ctrl.Message }}</div> 直接套用樣式的方法來解決了
以上這短篇就是紀錄學到的 AngularJS 載入流程與改善體驗的方式
謝謝收看~~
AngularJS 學習筆記系列 : (依本人的上進心持續增加)
AngularJS 初學者筆記與教學 (一) - 使用方式、Expression、Controller、Module
AngularJS 初學者筆記與教學 (二) 內建的簡單指令之1 ng-click、ng-show、ng-hide
AngularJS 初學者筆記與教學 (三) - AngularJS 的載入流程與 ng-cloak 運作原理
AngularJS 初學者筆記與教學 (四) - 如何動態改變 CSS 樣式,使用 ng-class、ng-style
AngularJS 初學者筆記與教學 (五) - 繼續深入學習常用的 ng-repeat
AngularJS 初學者筆記與教學 (新手入門課程 - 課後心得篇)
AngularJS 初學者筆記與教學 (七) - FormController 的表單驗證與資料檢查