這是Jerry 2021年的第 14 篇文章,也是汪子熙公衆號總共第 285 篇原創文章。css
在本篇文章以前,Jerry 印象最深的幽靈,應該要算《星際爭霸I》里人族可以隱形的空中單位 Wraith( 幽靈戰機 ),以及能施放核彈的 Ghost( 幽靈特工).html
上週 Jerry 作 SAP Spartacus 開發時,接觸到一個新的和幽靈相關的術語:編程
讀了幫助文檔後,發現該名詞對我來講只不過是舊瓶裝新酒罷了。數組
我對應用軟件的 User Experience 即用戶體驗領域知之甚少。在 SAP 內部,有專門的用戶體驗設計師負責這個領域,所以我也不清楚 Skeleton / Ghost Design 準確的中文翻譯是啥,姑且就直譯成「幽靈設計」吧。瀏覽器
在我看來,不管是幽靈設計,仍是以前 SAP UI5 提供的頁面加載動畫效果,都是改善用戶使用體驗的一種手段:提示用戶當前頁面正在加載後臺數據,或是執行一些比較費時的操做。服務器
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/y3225...
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 的外觀,已經變成了三個大小不斷變化的圓圈。
我在 2015 年擔任 一個德國 Fiori 客戶上線的 Dev Angel 時,該客戶有一個自開發需求:其產品主數據的配圖動輒超過 10 MB,客戶但願瀏覽器在成功加載這些尺寸巨大的圖片以前,顯示一些加載動畫效果。待到圖片徹底加載結束時,再關閉加載動畫,顯示實際圖片。
先看沒有通過任何優化處理的狀況下,如何在 SAP UI5 裏使用 Image 控件顯示一個 url 指向的圖片:第10行調用 SAP UI5 控件 Image 實例的 setSrc 方法,加載 BIG_IMAGE 變量指向的圖片。
再看我給客戶推薦的基於圖片代理的解決方案。
這是運行時的效果:
https://v.qq.com/x/page/n3225...
這個方案實現源代碼以下:
上圖代碼按照運行時執行的前後順序,有4個關鍵點,分別用序號1~4表示:
Spartacus 裏的 Spinner 控件做用相似 SAP UI5 Busy Dialog,下面是一個例子:當第九行代碼的組件屬性 supportedDeliveryModes$.length 可用時,說明當前訂單支持的商品遞貨模式的相關配置信息,已經從後臺取到前臺了,此時顯示遞貨模式的選擇頁面;不然,則顯示 ID 爲 loading 標識的模板頁面,裏面只包含一個 Spinner 控件:
這個 Spinner 控件的外觀及實現細節,請參考 Jerry 的視頻:
https://v.qq.com/x/page/w3160...
最後來講說 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 觸發了某些後臺數據加載時,爲了提高用戶體驗而引入的一些頁面效果的技術實現,但願對你們有所幫助,感謝閱讀。
更多閱讀
更多Jerry的原創文章,盡在:"汪子熙":