葡萄城的一款尚在研發中的產品,對外名稱暫定為X專案。其中使用了已經上市的Wijmo中SpreadJS產品,另外,在研發過程中整理了一些研發總結分享給大家。如本篇的在頁面切換的過程中優化方案,歡迎大家跟帖交流。

前言

AngularJS被用來開發單頁面應用程式(SPA),利用AJAX呼叫配合頁面的區域性重新整理,可以減少頁面跳轉,從而獲得更好的使用者體驗。Angular的ngView及其對應的強大路由機制,是實現SPA應用的核心模組。本文所說的頁面切換指的就是這個路由機制,即根據不同的URL展示不同的檢視。

有一種非常常見的場景:在切換至新頁面後,需要通過AJAX呼叫從伺服器請求一些資料,然後根據這些資料來展示頁面。如果未做任何處理,那麼頁面會先載入新頁面的html模版,但此時模板中的資料model還並沒有被請求,因此會有一段時間顯示空資料,非常影響使用者體驗。

場景

讓我們以Angular官方給出的 PhoneCat Tutorial App來說明這個問題。

在PhoneCat專案的github主頁上有這麼一段話:“There is no dynamic backend (no application server) for this application. Instead we fake the application server by fetching static json files.”也就是說,這個示例專案中只是模擬了一個server,所以當頁面請求phones.json和每個手機的詳細資料時,這些請求會在非常短的時間內就完成了,我們並感覺不到展示頁面存在什麼問題。

而在真實的網路環境中,請求這些json檔案可能會消耗相對較長的時間。讓我們來模擬一下網路請求響應時間較長的情況。在這裡我用了express來代替原來的http-server,並在客戶端請求資料時延遲5秒再做出響應:

執行起來後可以看到,頁面立即會顯示出來,但是原本應該顯示手機列表的區域是一片空白,直到5秒之後才將列表資料顯示出來。點選一個手機名稱進入詳細資訊頁面,同樣是一開始只顯示了html模板的內容,然後才將引數資料填充到頁面上。過程中頁面會出現抖動,非常影響使用者體驗。

使用resolve來提前請求資料

在遇到這個問題時,我最先想到的就是新增一個loading提示:在網路請求前顯示loading遮罩圖片,網路請求結束後再將其隱藏。於是點選進入手機的detail頁面後頁面會呈現一個loading圖片,像下圖這樣:

可以看到,頁面應該顯示手機詳細資料的區域顯示空白,造成非常不好的使用者體驗。這是因為PhoneDetailCtrl的程式碼是在頁面跳轉發生後才執行的,而此時手機資訊資料還沒有從伺服器獲取到,也就是說$scope.phone這個model還未被賦值。有沒有一種辦法讓這些資料在切換到這個頁面之前就先準備好呢?

答案當然是有,也就是這篇文章要介紹的主角——resolve。我們知道ng-view是通過$routeProvider來訂製頁面路由規則,這個路由規則在phonecat專案原始碼中是這樣定義的:

為了讓頁面跳轉之前執行一些事情,我們可以在路由規則中配置resolve引數。

Resolve引數可以注入一組service到路由繫結的controller之中。如果其中的一個或多個service是非同步物件($q.defer)時,那麼只有當這些非同步操作都完成後,頁面才會跳轉。利用這一點,我們就可以在頁面跳轉前先將手機詳細資訊資料請求到本地。跳轉後,目標頁面就會立即正常顯示資料。

我將手機詳細資訊頁面的路由配置程式碼修改如下:

在上面的程式碼中,我只能使用$route.current.params來獲取phoneId引數,因為此時頁面還未跳轉,$routeParams是獲取不到任何值的。經過這樣配置resolve引數後,我就可以在PhoneDetailCtrl中注入一個名為phoneDetailsService的物件。PhoneDetailCtrl的程式碼如下:

這樣,就可以在頁面跳轉之前獲取到請求的資料了。

為頁面加入切換動畫

為了讓頁面間的切換更平滑,可以在頁面切換加入過渡動畫。AngularJS對一些常用的指令比如ngRepeat、ngSwitch以及ngView都有動畫的支援。

AngularJS通過CSS來定義動畫,要實現DOM元素的動畫效果非常簡單。當DOM元素變化的時候,AngularJS會在元素上新增特定的class:

· ng-enter,當元素被新增時會被應用;

· ng-move,當元素被移動時會被應用;

· ng-leave,當元素被刪除時會被應用。

我們可以對ng-view應用AngularJS動畫,在phone-cat專案中,animation.css中的下列程式碼實現了切換頁面的淡入淡出動畫:

.view-frame.ng-enter,
.view-frame.ng-leave {
background: white;
position: absolute;
top: 0;
left: 0;
right: 0;
} .view-frame.ng-enter {
-webkit-animation: 0.5s fade-in;
-moz-animation: 0.5s fade-in;
-o-animation: 0.5s fade-in;
animation: 0.5s fade-in;
z-index: 100;
} .view-frame.ng-leave {
-webkit-animation: 0.5s fade-out;
-moz-animation: 0.5s fade-out;
-o-animation: 0.5s fade-out;
animation: 0.5s fade-out;
z-index: 99;
}

總結

在Web應用中,為了獲得良好的使用者體驗,就要在介面上使用一些技巧讓使用者不會感覺到突兀。本文提出了兩點技巧讓AngularJS應用在頁面切換時更加自然平滑。

另外,在實際開發過程中,還可以適當選用開發工具減輕部分程式碼量,對專案進度有較大的幫助。目前,支援AngularJS的開發工具不多,Wijmo是較有優勢的一個,點選此處能看到對Angular 2 的具體支援情況。微軟Dynamics 使用 Wijmo 5提供移動端使用者介面選擇。

完整demo下載地址:AngularJS應用頁面切換優化方案

相關閱讀:

開放才能進步!Angular和Wijmo一起走過的日子

Angular vs React 最全面深入對比

Wijmo已率先支援Angular4 & TypeScript 2.2