写点什么

深入学习 SAP UI5 框架代码系列之四:SAP UI5 控件的元数据实现

作者:Jerry Wang
  • 2021 年 11 月 28 日
  • 本文字数:2041 字

    阅读完需:约 7 分钟

深入学习 SAP UI5 框架代码系列之四:SAP UI5 控件的元数据实现

在本系列的第二篇文章:深入学习SAP UI5框架代码系列之二:UI5 控件的渲染器 里,我们了解了什么是 UI5 控件的渲染器(Renderer), 以及如何从 SAP UI5 控件的元数据里,获得其对应渲染器的名称:sap.ui.commons.ButtonRenderer



本文我们将了解更多关于 SAP UI5 控件元数据的细节。虽然作为 SAP UI5 应用开发人员,我们日常工作中,最经常打交道的,是本系列下一篇文章要介绍的 SAP UI5 控件的实例数据。但是,了解了 SAP UI5 控件元数据的设计原理,有助于 SAP UI5 开发人员,理解我们本地使用 Visual Studio Code 或者浏览器里使用 WebIDE, SAP Business Application Studio 这种在线开发工具时, SAP UI5 代码自动补全的实现原理。


如何在运行时获取 SAP UI5 控件的元数据?


拿到控件实例后,调用其 getMetadata()方法即可。


在下图第 19 行设置断点,拿到 button 控件实例 oButton1, 调用其 getMetadata 方法,返回值就是 button 控件的元数据,如下图右边所示。


元数据里字段很多,这里只介绍对 SAP UI5 应用开发人员来说最重要的一部分字段:


_aAllPublicMethods

当我们在 Chrome 开发者工具的 console 面板里,输入 oButton1 之后,紧接着再敲一个"."(英文输入状态下的句号),就能看到该 button 实例能够调用的一系列公有方法。这些公有方法列表,维护在元数据里的数组_aAllPublicMethods.



这个数组的 length 为 110,这意味着 button 实例总共可以调用 110 个公有方法。然而我们在 Button.js 里查看 button 的实现源代码,发现里面能够找到的方法数目远远小于 110.


这是因为 button 控件实例能调用的 110 个公有方法,很多都来自其原型链继承关系上游的节点里实现的公有方法。


回顾本系列第一篇文章 深入学习SAP UI5框架代码系列之一:UI5 Module的懒加载机制 提到的 SAP UI5 控件原型继承链:

Button->Control->Element->ManagedObject->EventProvider->BaseObject

想判断一个方法是 button 本身所实现,还是从其原型链继承过来的,可以将方法名称传入函数 oButton1.hasOwnProperty, 通过其返回的布尔值得知结果。


比如 getText 是 button 原型链上的一个方法,因此下面的 JavaScript 语句返回:false.




_aAllPublicMethods 数组的填充逻辑:控件本身的公有方法和其原型链上级节点的公有方法的并集(下图高亮 JavaScript 代码里数组的 concat 操作)


_aPublicMethods

该数组内的元素是刚刚介绍过的_aAllPublicMethods 的一个子集,定义在 metadata 的_publicMethods 字段内。下图是 UI5 控件原型链上的节点,EventProvider 的 publicMethods:



_mAllAggregations

该对象维护了控件所有可用的 Aggregation.


在面向对象编程领域,我们常用 association, aggregation(聚合)和 composition(组合)描述类与类,对象与对象之间的关联关系。


Aggregation 描述的是 has-a 的语义,在 UML 图里通过空心菱形箭头表示,比如 tooltip 可以脱离 button 控件单独存在;Composition 关系描述 part-of,即部分和整体的语义,用实心菱形箭头表示。



下图是一个例子:button 控件的 tooltip 以 Aggregation 的方式维护和存储在控件元数据当中,通过 getTooltip 和 setTooltip 进行读写访问。




关于 SAP UI5 Aggregation 的权威介绍,可以查看 SAP UI5官网.


官网里给出的一个例子,TextList 的元数据里定义了一个指向 texts 的 aggregation, 关系为 1:N.


_mProperties

该对象包含了 button 控件所有可用的属性,以及针对这些属性的读写方法。注意 mProperties 存储的只是控件属性的元数据,而非属性运行时的值。SAP UI5 控件运行时属性值的存储,会在本系列下一篇文章 UI5 控件的实例数据实现细节 里介绍。


_oParent

指向该控件原型链父节点的元数据存储结构。顺着节点的 oParent 字段,我们可以遍历完整个原型链。



SAP UI5 button 控件的公有方法,从 Jerry 2015 年写作时的 110 个,增添到了 2021 年 1.85.0 版本里的 127 个:



我们有两种方式可以手动计算出 127 这个数字。


方法 1:button 元数据的_aPublicMethods.length + _oParent._aAllPublicMethods.length



方法 2:button 自身,及其原型链上每个节点元数据的_aPublicMethods.length 求和:



Jerry 最近用 Angular 开发 SAP Spartacus 时,也会在 Angular Component 的 template 文件里使用控件。


这些控件的实现分为三类:


(1) 直接利用 HTML 原生标签,例如 div, span, label, input 这些:



(2) 由前缀为 cx-的选择器代表的复合控件,这是我们团队开发的能够被 SAP Spartacus 其他 UI 和二次开发人员重用的控件,cx 即 Customer Experience.


比如下列高亮代码的语义是,如果当前 Component 的 orderApproval 模型处于可用状态,且 loading 标志位为 true,则显示一个旋转的动画效果,即加载第四行的复合控件 cx-spinner, 否则加载 id 为 approvalFormTemplate 的页面模板。复合控件本质上仍然是一个 Angular Component:



对于以上这两种控件实现,不存在类似 SAP UI5 那样的源代码级别的元数据数据结构。


(3) 第三方提供的控件库,比如 ng-select, 一个下拉菜单控件库:




在 node_modules 文件夹下的 ng-select.component.d.ts 文件里,即可找到类似 SAP UI5 控件的元数据定义:



本系列下一篇文章,我会介绍 SAP UI5 控件实例在运行时的属性值存储和读取实现,感谢阅读。

发布于: 4 小时前阅读数: 8
用户头像

Jerry Wang

关注

个人微信公众号:汪子熙 2017.12.03 加入

SAP成都研究院开发专家,SAP社区导师,SAP中国技术大使。

评论

发布
暂无评论
深入学习 SAP UI5 框架代码系列之四:SAP UI5 控件的元数据实现