本文是深入学习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的原创文章,尽在:“汪子熙”:

深入学习SAP UI5框架代码系列之一:UI5 Module的懒加载机制相关推荐

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

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

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

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

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

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

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

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

  5. 深入学习SAP UI5框架代码系列之三:HTML原生事件 VS UI5 Semantic事件

    这是Jerry 2020年的第80篇文章,也是汪子熙公众号总共第262篇原创文章. 系列目录 (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框架代码系列之八:谈谈 SAP UI5 的视图控件 ID,以及 SAP UI5 视图和 Angular 视图的异同

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

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

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

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

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

最新文章

  1. MySQL 不完全入门指南
  2. linux下C程序:运行单个实例
  3. 如何解决div层被flash遮盖的问题
  4. PMCAFF | 从200块到300万,史上最全自媒体报价单
  5. cocos2d-x学习 之一
  6. C#LeetCode刷题之#720-词典中最长的单词(Longest Word in Dictionary)
  7. vga/dvi/hdmi/dp
  8. java语言cd_java语言
  9. 【 以项目实战讲解CAD的二次开发(二)】
  10. C++学习 十五、类继承(4)基类方法重写,隐藏
  11. 【摘录】大学课程对照英文翻译
  12. python写一个数字字典生成器
  13. Redux Reducer
  14. 深踩 AndroidStudio 缓存的坑
  15. 牛逼的Android UI
  16. Server Error in ‘/‘ Application.问题解决
  17. 钓鱼Wi-Fi搭建实践
  18. 知识管理从建立知识库做起
  19. 害怕失败,所以全力以赴
  20. 利用尾插法建立单链表

热门文章

  1. Binlog参考资料
  2. 期望+DP ZOJ 3929 Deque and Balls
  3. 关于ListView 自定义 Adapter的问题
  4. 从零写一个编译器(二):语法分析之前置知识
  5. 有关 MyEclipse-export runnable jar file选项 launch configuration里面没有可以选择的东西的解决方法...
  6. 003 Preconditons
  7. SpringCloud之声明式服务调用 Feign(三)
  8. web容器(03):Nginx配置负载均衡
  9. EditPlus注册码在线生成,强大
  10. YTU 1009: University