这是 Jerry 2021 年的第 37 篇文章,也是汪子熙公众号总共第 313 篇原创文章。
Jerry 之前的文章
一个 SAP 开发工程师十余年的技术写作之路回顾曾经提到,知乎上安晓辉老师的一篇文章:
那些很厉害的人是怎么构建知识体系的。
其中安老师有一个观点:
Jerry 前一篇文章 SAP Fiori Elements List Report Smart Table 列项目宽度计算的奥妙 介绍了相对比较现代的 SAP Fiori Elements 框架里,Smart Table 列项目宽度的决定逻辑。在写那篇文章的过程中,我回忆起了几年前研究过的 SAP CRM 和 SAP Cloud for Customer 这两个产品里表格宽度的调整逻辑。出于完善知识体系的目的,本文做一个简单的回顾。
SAP CRM 和 Cloud for Customer 都支持用户通过个性化设置来调整表格列项目的宽度。本文介绍这两个产品里,当用户调整表格列项目宽度时,背后发生的故事。
SAP CRM 里,点击工具栏上的按钮,进入表格的定制化模式。
指定表格内每个列项目宽度所占的百分比,然后保存。
保存之后,这些设定的百分比,存储到了 SAP CRM 后台数据库表 BSPC_DL_PERSSTOR 里面。根据修改宽度的用户名和修改时间查询这个表:
发现一条记录,以 XML 格式存储,维护了当前这次宽度自定义调整的明细,比如每个列项目新的宽度百分比。
当下一次包含该表格的页面被渲染时,存储在 BSPC_DL_PERSSTOR 数据库表里的自定义后的列项目宽度百分比,被读取出来,用于 UI 的渲染操作。
Jerry 之前的文章 SAP UI和Salesforce UI开发漫谈 提到,SAP CRM WebClient UI 基于 BSP,是一门服务器端渲染技术。SAP CRM UI Component 的渲染器,CL_CHTMLB_CONFIG_CELLERATOR, 负责服务器端 HTML 源代码的生成。
再看 SAP Cloud for Customer,用户调整表格列项目宽度的方式更加简捷,鼠标放在两个列项目的交界处,按住不放,左右拖拽即可。
然而,我们仍旧可以通过单步调试的办法,在 SAP Cloud for Customer 前台实现源代码里,找到 HTTP POST 请求的原始负载被 GZIP 压缩之前的地方设置断点,在 Chrome 调试器里即可查看该负载。
在 FunctionModule.js 调用 sendAsyncPostRequest 函数之处设置断点,我们要查看的 HTTP POST 负载就维护在第三个参数 sRequestString 里:
请求负载的正文是一个 JSON 对象,CONTENT 的内容为 BASE64 编码之后的值:
将其用 BASE64 解码工具进行解码后,发现 CONTENT 字段原始内容的格式为 XML,根节点 ChangeTransaction,这是 SAP Cloud for Customer 记录用户通过 Key User Tool 或者 Personalization 功能对 UI 进行调整的明细的数据结构。
上面 XML 源代码里和列项目宽度更改相关的属性,高亮显示在下图红色区域。UI 调整类型为 ChangeColumnWidth, 调整后的值为 267 px:
按 F5 刷新浏览器,表格重新绘制时,SAP Cloud for Customer 会首先通过一个 HTTP 请求,从后台读取该表格各个列项目新的宽度值,如下图高亮区域所示。
Jerry 之前的同事曾经发表过一篇文章 SAP Cloud for Customer 使用SAP UI5的独特之处,介绍了 SAP C4C UI 也是基于 SAP UI5 实现的。因此,SAP C4C 表格渲染,按照 Jerry 之前文章 深入学习SAP UI5框架代码系列之二:UI5 控件的渲染器 介绍的原理,同样是通过表格控件对应的渲染器,TableRender.js 完成。
从 SAP C4C 后台读取到的新的表格列项目 267 px,在渲染器的 renderTableControlCnt 函数里,参与列项目的渲染逻辑:
渲染完毕后,从 Chrome 开发者工具的 Elements 标签页里,能观察到,刷新后该列项目的宽度和刷新前我们新调整的宽度一致。