SAP Fiori 里的 List 是如何做到懒加载 Lazy load 的
今天一同事问我这个问题:S/4HANA Fiori 应用里的列表,一旦 Scroll 到底部就会自动向后台发起新的请求把更多的数据读取到前台显示。
以 Product Master 这个应用为例,我点击搜索之后,结果区域显示当前系统一共有 140 个 product,但是只有前 25 个返回并显示在浏览器里。
这个分页效果是 UI5 OData 的参数实现的:$skip=0&top=25。
而总数 140,是通过参数 $inlinecount 实现,其原理和 ABAP Open SQL 的 SELECT COUNT(*)类似。
从 Chrome 开发者工具能观察到头 25 个 product 的 payload:
当将列表滚动至底部时,第二批共 25 个 product 从后台读取出来,显示在前台:
这个 http 请求的参数:$skip=25&top=25,用于读取从第 25 个到第 50 个 product。
从调用栈能清楚发现是 scroll 这个事件触发的第二批 product 的读取动作。
然后再去 GrowingEnablement.requestNewPage 这一个调用栈,发现一个属性_iLimit 维护了一个开始索引,每次 scroll 到底部的事件触发之后,该属性值都会被 GrowingThreshold 累加。 因为 API this._oControl.getGrowingThreshold 每次返回的是一个常量 25, 因此_iLimit 的值每次 scroll 到底部之后看起来是这样的:25,50,75,100 ... 这些值会被用来作为 HTTP 请求参数 $skip 的值传到后台:
我同事的问题:growingThreshold 在文件 sap.m.ListBase.js 里被硬编码成 20, 但是运行时在何处被改写成了 25?
要回答这个问题,需要了解一些 UI5 Smart Template 的知识,因为例子里这个 Product Master 的 Fiori 应用,也是基于 Smart Template 开发的。可以参考我的博客My understanding about how object page in Smart Template is rendered 来了解其工作原理。
当 Product Master 这个应用的 UI Component 被加载并马上开始渲染时,需要先加载 Smart Template 的库文件:
在我博客My understanding about how object page in Smart Template is rendered 提到,ListReport.view.xml 这个文件里有若干 view fragment 的声明,每个声明指向了一些其他的 Smart Template 库文件。
这些库文件一览:
在 Chrome 开发者工具查看从 ABAP 后台加载的库文件 SmartTable.fragment.xml,能发现属性 growingThreshold 在此处被硬编码成 25。
当 SmartTable.fragment.xml 被加载之后其内容会被解析, growingThreshold 值为 25,会通过控件的 setter API 写入到控件属性里。这样接下来在处理列表的 scroll 事件是,25 这个值就会通过控件的 getter API 返回并累加到_iLimit 上。
关于 XML view 从 ABAP 后台加载到浏览器后是如何被解析并生成对应的 UI5 控件,可以参考我的博客Why my formatter does not work? A trouble shooting example to know how it works
也许您按照我上面描述的步骤操作,但是无法触发断点。原因是因为 UI5 框架针对基于 Smart Template 开发的 Fiori 应用的 XML view 设计了一套缓存机制。当待渲染的 XML view 已经在缓存中存在时,不会去 ABAP 后台加载 Smart Template 的库文件, 而是直接执行第 428 行的 IF 分支。
通过调试我们可以发现缓存是通过 IndexedDB 加上 LRU(Least recently used)算法实现的。
通过 Chrome 开发者工具可以观察到待渲染的 view 已经有记录存储在 IndexedDB 里了:
如果想观察 Smart Template 库文件的加载,需点击"Delete database"以手动清除缓存。
缓存清除完毕后,即可观察到期望中的 Smart Template 库文件加载。
这篇文章介绍了如何通过调试找到同事提出问题的答案。我把它加在了我 UI5 调试文章分享的合集里:My UI5 debugging tips and experience collection - how to resolve UI5 issues through debugging by yourself
要获取更多 Jerry 的原创技术文章,请关注公众号"汪子熙":
版权声明: 本文为 InfoQ 作者【Jerry Wang】的原创文章。
原文链接:【http://xie.infoq.cn/article/642108f00d632cfa2bad5dac6】。
本文遵守【CC-BY 4.0】协议,转载请保留原文出处及本版权声明。
评论