本文是深入学习SAP UI5框架代码系列的第二篇文章。

系列目录

  • SAP UI5应用开发人员了解UI5框架代码的意义
  • UI5 module懒加载机制
  • UI5 控件渲染机制
  • HTML原生事件 VS SAP UI5 Semantic事件
  • UI5控件元数据实现细节
  • UI5控件的实例数据实现细节
  • UI5控件数据绑定的实现原理
  • UI5控件数据绑定的三种模式:One Way,Two Way和OneTime实现原理比较
  • UI5控件ID的生成逻辑
  • UI5控件的多语言(国际化,Internationalization,i18n)支持的实现原理
  • XML视图里的button控件
  • button控件和它背后的DOM元素

通过Jerry前一篇文章 一个用于SAP UI5学习的脚手架应用,没有任何后台API的依赖 介绍的脚手架应用,创建一个只包含一个Button控件的UI5应用:

浏览器里打开,总共触发了18个请求,网络传输流量1.1MB, 页面总共加载了5.1MB资源(见下图底部紫色矩形框所示)。

顺便说一说,为什么页面加载的资源尺寸(5.1 MB)会大于网络传输的数据量(1.1 MB)?

网上有一种说法,页面加载的资源,是通过网络加载的资源,以及从浏览器缓存读取的资源总和,因此会出现Chrome开发者工具里显示的页面加载的资源尺寸大于网络传输数据量的情况。

这种说法不完全正确。更准确的说,页面加载资源统计的是前端页面加载的所有资源,经过解压之后的原始大小。

如图,打开Chrome开发者工具的Use Large request rows选项, 就能显示出经过网络加载资源解压缩过后的原始大小,如下图所示:

以上说明来自Google官网: https://developers.google.com/web/tools/chrome-devtools/network/reference#uncompressed

回到我们的UI5应用,Ctrl+Alt+Shift+P,选中"Use Debu Sources",让SAP UI5加载调试版本的库文件:

待button显示在页面之后,打开Chrome开发者工具Sources面板,能看到sap/ui文件夹下多出来一个commons文件夹:

回忆一下我们的脚手架应用的代码里,新建了一个命名空间sap.ui.commons下的Button控件实例:

因此运行时,SAP UI5对应的Button Module会被加载。Button-dbg.js负责Button的生命周期管理和事件响应,ButtonRenderer-dbg.js负责将Button实例渲染成原生的HTML代码。

切换到Network标签页,选择任意一个Button Module加载的网络请求,把鼠标hover到Initiator列上,在弹出窗口就能看到一个调用栈,从中就能观察到是index.html即Button控件的消费者,触发了这两个Button Module的加载。

在index.html里实例化Button控件的代码处设置断点,重新刷新应用。因为sap.ui.commons.Button并不是原生的HTML element,所以调试器执行到代码第11行并且单步执行后,会触发Button Module的加载:

这就是SAP UI5 Module的懒加载机制:如果该页面没有用到Button控件,则对应的Button Module永远不会被加载。

下图sap-ui-core-dbg.js第26384行就是Button Module的加载入口,注意注释里lazy stub for XXX的提示:

requireModule准备加载sap/ui/commons/button.js这个Module文件:

Module文件通过AJAX被加载后,SAP UI5得到的只是纯字符串文本,还无法直接用其创建button实例。SAP UI5会调用浏览器原生API, window.eval(), 将button.js文件的字符串内容传入该API,执行结果是一个JavaScript对象,也就是SAP UI5 Button Module的运行时实体。

SAP UI5运行时为所有的Module维护了一个注册表,以键值对的数据结构存储了这些Module的信息,键的数据类型为string,值类型即window.eval()执行加载好的JavaScript文件内容后返回的JavaScript对象。

Module的可能状态为一系列枚举值:INITIAL, LOADED, READY, FAILED, PRELOADED.

回到我的例子,因为我的代码触发了Button Module的第一次加载,所以代码第16487行,将Module的状态标注为INITIAL.

继续调试:

  • Line 16514: 将Button Module状态设置为LOADING.
  • Line 16517: 根据全局标志位window.sap-ui-loaddbg的值决定加载Button Module的普通版本还是调试版本。
  • Line 16520: 根据Module名称获得待加载Module的url.
  • Line 16525: 使用jQuery.AJAX加载Button-dbg.js.

因为该Module若不加载完成,则我们代码里的new sap.ui.commons.Button无法继续下去,因此这里的AJAX调用以同步模式进行( async = false ). 在其成功加载的回调函数里,将Module状态设置为LOADED, response变量包含的就是Button-dbg.js的文本内容。

Module状态为LOADED,说明其文本内容已经加载完成,可以交给16543行的execModule函数执行了(注意该函数上面的IF条件)。

代码第16612,如调试器所示:变量sScript包含的就是Button-dbg.js的文本内容,待window.eval()执行完毕后,Module的状态设置为READY:

new sap.ui.commons.button这行语句看似仅仅是一个简单的实例构造操作,背后却隐藏着SAP UI5控件设计的思路。

SAP UI5的注释写的很清楚:首先用工厂方法创建一个新的空Button实例oInstance,然后再使用消费者调用new sap.ui.commons.Button时传入的参数对oInstance进行enrich:

我们查看Button Module的源代码,发现通过JavaScript的原型继承,Button的prototype为Control:

查看SAP UI5官网上对sap.ui.core.Control的说明:

  • Rendering: 每个SAP UI5控件都有对应的Renderer,被RenderManager调用负责生成原生的HTML代码。
  • 显示/隐藏,Busy Indicator,支持关联自定义的CSS样式类,注册浏览器事件。

Control的原型是Element:

Element是SAP UI5页面的基本元素,主要用于UI5的内部实现。

Element的原型是ManagedObject:

因为这条原型链过长,Jerry就不一一截图了,大家只需要记住结论:从Button控件出发,沿着它的原型链往上回溯,最后会到达BaseObject(相当于ABAP/Java里的Object).

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

因此,在执行Button自己的构造函数之前,其原型链上每个节点的构造函数会依次执行一次:

本系列下一篇文章:UI5 控件渲染机制。

感谢阅读。

更多Jerry的原创文章,尽在:"汪子熙":

webbrowser控件 加载为空白_深入学习SAP UI5框架代码系列之一:UI5 Module的懒加载机制...相关推荐

  1. 深入学习SAP UI5框架代码系列之八:谈谈 SAP UI5 的视图控件 ID,以及 SAP UI5 视图和 Angular 视图的异同

    今天是 2021 年 4 月 27 日,周二,SAP 全球心理健康日.SAP 全球的员工,今天放假一天. 这不,早在上周五,我所在的 SAP Spartacus 开发团队的开发经理,就贴心地在 Sla ...

  2. 深入学习SAP UI5框架代码系列之七:控件数据绑定的三种模式 - One Way, Two Way和OneTime实现原理比较

    这是Jerry 2021年的第 8 篇文章,也是汪子熙公众号总共第 279 篇原创文章. 系列目录 (0) SAP UI5应用开发人员了解UI5框架代码的意义 (1) SAP UI5 module懒加 ...

  3. 深入学习SAP UI5框架代码系列之六:SAP UI5控件数据绑定的实现原理

    这是Jerry 2021年的第 7 篇文章,也是汪子熙公众号总共第 278 篇原创文章. 系列目录 (0) SAP UI5应用开发人员了解UI5框架代码的意义 (1) SAP UI5 module懒加 ...

  4. 深入学习SAP UI5框架代码系列之五:SAP UI5控件的实例数据修改和读取逻辑

    这是Jerry 2021年的第6篇文章,也是汪子熙公众号总共第277篇原创文章. 系列目录 (0) SAP UI5应用开发人员了解UI5框架代码的意义 (1) SAP UI5 module懒加载机制 ...

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

    这是Jerry 2021年的第5篇文章,也是汪子熙公众号总共第276篇原创文章. 系列目录 (0) SAP UI5应用开发人员了解UI5框架代码的意义 (1) UI5 module懒加载机制 (2) ...

  6. 深入学习SAP UI5框架代码系列之二:UI5 控件的渲染器

    这是Jerry 2020年的第79篇文章,也是汪子熙公众号总共第261篇原创文章. 系列目录 (0) SAP UI5应用开发人员了解UI5框架代码的意义 (1) UI5 module懒加载机制 (2) ...

  7. 深入学习SAP UI5框架代码系列之一:UI5 Module的懒加载机制

    本文是深入学习SAP UI5框架代码系列的第二篇文章. 系列目录 SAP UI5应用开发人员了解UI5框架代码的意义 UI5 module懒加载机制 UI5 控件渲染机制 HTML原生事件 VS SA ...

  8. 通过最简单的button控件,深入学习SAP UI5框架代码系列之零

    Jerry曾经作为SAP成都研究院的Fiori应用开发人员,从事了将近3年的SAP CRM Fiori应用开发,在使用SAP UI5的过程中,遇到过形形色色的问题,不少都是通过调试SAP UI5框架代 ...

  9. python的控件text的文本属性_只需6行Python代码就给图片加上水印——你一看就会了...

    大家在做项目开发的过程中,会不会经常遇到需要处理图片却没有快速有效的工具的情况呢?比如客户需要给图片加上水印,你可能会用到PS这些高级软件去处理,这样虽然有效果但是需要相对较长的时间:作为程序猿,你一 ...

最新文章

  1. ACM MM 2021 | 面向多模态情绪识别的双流异质图递归神经网络
  2. 替换SAP Fiori Logo不成功的workaround
  3. [vue-element] ElementUI使用表格组件时有遇到过问题吗?
  4. 前端学习(675):if else if
  5. oracle 未找到段的存储定义,Exp-00003 no storage definition found issue in oracle 11g (未找到段 (0,0) 的存储定义)...
  6. LeetCode 261. 以图判树(全部连通+边数=V-1)
  7. Nginx学习之如何搭建文件防盗链服务
  8. Cannot find class [***] for bean with name '***' defined in file[***]
  9. MySQL核心之分组函数(sum() avg() min() max() distinct count() )
  10. 静态网页怎么用html语言编写,简单html静态网页代码 用html编写一个静态网页
  11. 【python爬虫专项(27)】拉勾网数据采集(关键词网址不发生变化)
  12. Carte+kettle+mysql性能问题定位分析记录
  13. Ai 缺失字体解决方法
  14. 报错org.apache.ibatis.builder.BuilderException: Error creating SqlSource for SqlProvider. Method ‘inse
  15. 解决: ORA-02199: missing DATAFILE/TEMPFILE clause [Oracle OMF 功能详解]
  16. Python 视频教程百度云分享
  17. [喜闻乐见]期末尻♂总结
  18. 步步惊心的三文鱼财富
  19. Ubuntu1804里进行KITTI数据集可视化操作
  20. 创建vue项目,vue项目自定义配置

热门文章

  1. 第二阶段冲刺之站立会议1
  2. bzoj2763 [JLOI2011]飞行路线
  3. DownList下的部门树
  4. 【信息系统项目管理师】第12章-项目采购管理 知识点详细整理
  5. 【Python】排序函数 sort、sorted 对复杂列表排序
  6. C++中不能声明为虚函数的有哪些函数
  7. 移植gettimeofday
  8. Linux搭建arm的qemu模拟器
  9. nginx开发从入门到精通【淘宝核心系统服务器】
  10. python3.7中Gluonts与Mxnet安装问题