SAP UI的加載動畫效果和幽靈設計(Ghost Design)
上周 Jerry 做 SAP Spartacus 開發時,接觸到一個新的和幽靈相關的術語:

Skeleton Design(Ghost Design)
讀了幫助文檔后,發現該名詞對我來說只不過是舊瓶裝新酒罷了。
本文目錄
SAP UI5 Busy Dialog
使用代理模式( Proxy Pattern ) 提高 SAP UI5 大尺寸圖片的加載體驗
SAP Spartacus Spinner 控件
SAP Spartacus 幽靈設計
我對應用軟件的 User Experience 即用戶體驗領域知之甚少。在 SAP 內部,有專門的用戶體驗設計師負責這個領域,因此我也不清楚 Skeleton / Ghost Design 準確的中文翻譯是啥,姑且就直譯成“幽靈設計”吧。
在我看來,無論是幽靈設計,還是之前 SAP UI5 提供的頁面加載動畫效果,都是改善用戶使用體驗的一種手段:提示用戶當前頁面正在加載后臺數據,或是執行一些比較費時的操作。
SAP UI5 Busy Dialog
Jerry 從2014年開始使用 SAP UI5 進行 Fiori 開發,經歷了 Fiori 1.0 到 2.0 的版本迭代。還記得處理的第一個 CRM Fiori 應用 My Opportunities 的 bug,癥狀就是修改了 Opportunity 數據之后,用戶可以短時間內快速點擊下圖的 Save 按鈕,從而產生多個到 CRM 后臺的 OData 保存請求。
當時我的修復該問題的策略就是,在 Save 按鈕點擊之后,設置一個 Busy Dialog,讓其鎖住整個頁面。這樣,用戶沒有機會再點擊 UI 進行任何操作了。直至 OData 請求在后臺成功完成,或者收到錯誤提示,再關閉該 Busy Dialog,頁面就能重新恢復可點擊狀態。
在 Fiori 1.0 時代,Busy Dialog 的外觀是一個由5朵花瓣組成的花朵,具有不斷旋轉的動畫效果。
可以通過這個視頻查看運行時效果:
https://v.qq.com/x/page/y3225pbaqpa.html
Jerry 曾經寫過一篇 SAP 社區博客:Fiori Busy Dialog – when is it opened and closed
該文章介紹了 SAP UI5 Busy Dialog 在 Fiori 應用中的使用場景。
一個典型的例子是,用戶點擊 Fiori Launchpad tile,跳轉到某個具體的 Fiori 應用時,瀏覽器地址欄里的 url 發生變化, sap.ui.controller.doHashChange 會調用 BusyDialog.open 方法,繪制一個花瓣的動畫效果:
如 Jerry 之前的文章 深入學習SAP UI5框架代碼系列之二:UI5 控件的渲染器 所述,這個花瓣效果的實現 位于其渲染器 LoadingDialogRenderer 的方法 renderFioriFlower 內:
5片花瓣的視覺效果,通過5個 div 元素實現:
而花瓣旋轉的動畫效果,通過 div 元素 css 類的 animation 系列屬性實現:
到了 Fiori 3.0 ,Jerry 發現 Busy Dialog 的外觀,已經變成了三個大小不斷變化的圓圈。
使用代理模式( Proxy Pattern ) 提高 SAP UI5 大尺寸圖片的加載體驗
我在 2015 年擔任 一個德國 Fiori 客戶上線的 Dev Angel 時,該客戶有一個自開發需求:其產品主數據的配圖動輒超過 10 MB,客戶希望瀏覽器在成功加載這些尺寸巨大的圖片之前,顯示一些加載動畫效果。待到圖片完全加載結束時,再關閉加載動畫,顯示實際圖片。
先看沒有經過任何優化處理的情況下,如何在 SAP UI5 里使用 Image 控件顯示一個 url 指向的圖片:第10行調用 SAP UI5 控件 Image 實例的 setSrc 方法,加載 BIG_IMAGE 變量指向的圖片。
再看我給客戶推薦的基于圖片代理的解決方案。
這是運行時的效果:
https://v.qq.com/x/page/n32257vdvui.html
這個方案實現源代碼如下:
上圖代碼按照運行時執行的先后順序,有4個關鍵點,分別用序號1~4表示:
第10行代碼,創建一個新的 Image 實例,充當圖片代理的角色。
第15行代碼,UI5 應用里原始的 Image 實例,調用 setSrc 方法,傳入的不是實際的大圖片地址,而是一個存儲在本地的,表示圖片正在加載的 gif 文件( 客戶自己準備,一個該企業 Logo 旋轉的動畫效果). 這樣,用戶打開頁面時,首先映入眼簾的,是該本地 gif 文件 loading.gif 實現的不斷旋轉的動畫效果。
第16行代碼,將待加載大尺寸圖片的 url 通過輸入參數,傳遞給代理 Image 控件的 setSrc 方法。這會觸發瀏覽器發起對大尺寸圖片的加載。
第13行代碼,當代理 Image 控件觸發的大尺寸圖片加載完成后,觸發其 load 回調函數。該回調函數觸發,說明大尺寸圖片的數據已經完全加載到本地,此時在回調函數里,將大尺寸圖片的 url 設置給原始 Image 控件的 src 屬性,即可將該圖片顯示出來。
SAP Spartacus Spinner 控件
Spartacus 里的 Spinner 控件作用類似 SAP UI5 Busy Dialog,下面是一個例子:當第九行代碼的組件屬性 supportedDeliveryModes$.length 可用時,說明當前訂單支持的商品遞貨模式的相關配置信息,已經從后臺取到前臺了,此時顯示遞貨模式的選擇頁面;否則,則顯示 ID 為 loading 標識的模板頁面,里面只包含一個 Spinner 控件:
這個 Spinner 控件的外觀及實現細節,請參考 Jerry 的視頻:
https://v.qq.com/x/page/w3160fich85.html
最后來說說 SAP Spartacus 的幽靈設計。
Spartacus B2B 功能模塊里,正常的 Cost Centers 列表顯示如下:
在這些 Cost Center 的數據從后臺取回來之前,頁面顯示如下,這種設計在 SAP Spartacus的幫助文檔里,被稱為 Skeleton 或者 Ghost Design:
這些在真實數據尚未從后臺加載完畢之前,以“占位符”的方式顯示在前臺的灰色矩形條,綁定在 Angular Component 里的數據,就稱為幽靈數據( Ghost Data ).
從Spartacus list.service.ts 的實現源代碼能看出,幽靈數據就是一個 length 屬性值為10的空數組。
在 Chrome 開發者工具里,能觀察到這些幽靈數據具有對應的 CSS class,這使得它們具有灰色矩形的視覺外觀:
Cost Center 表格顯示的數據最終通過 list.service.ts 從 SAP Commerce Cloud 后臺取出,取數邏輯通過 Angular 響應式編程庫 RxJS的 pipe 方法驅動:第101行 switchMap 操作符里的箭頭函數,輸入參數 pagination 包含了去 Commerce Cloud 取數據使用的分頁設置,函數體 this.load 發送 HTTP 請求,消費 Commerce Cloud 的 OCC API. 而第102行的 startWith操作符,語義上相當于給 pipe 驅動的 Observable 流賦上一個初始值,該初始值即為 length 屬性為10的空數組。
這樣,從運行時序來說,任何消費 getData 函數返回的 Observable 對象的 Angular UI 組件,都會先顯示 startWith 設置的初始值,即幽靈數據。待從 Commerce Cloud 后臺加載的真實數據返回給瀏覽器之后,組件自動刷新并顯示這些真實的業務數據。
本文介紹了 Jerry 工作過的 SAP 產品里,當用戶操作 UI 觸發了某些后臺數據加載時,為了提升用戶體驗而引入的一些頁面效果的技術實現,希望對大家有所幫助,感謝閱讀。
Angular HTML JavaScript 渲染
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。