这是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的原创文章,尽在:"汪子熙":