SAP UI5 xml 视图里定义的控件,运行时如何创建其实例的?

入口函数在 XMLTemplateProcessor 里:

SAP UI5 xml 视图里定义的控件,运行时如何创建其实例的?_第1张图片

解析 xml 视图的源代码之后,调用 createRegularControls 进行实例创建:

SAP UI5 xml 视图里定义的控件,运行时如何创建其实例的?_第2张图片

这是我的 xml 视图源代码:


   
      
         
   
   

number 字段的绑定路径被解析了出来:

SAP UI5 xml 视图里定义的控件,运行时如何创建其实例的?_第3张图片

在 BindingParser 的代码里,上述字符串类型的绑定路径,被解析成了 json 对象:

SAP UI5 xml 视图里定义的控件,运行时如何创建其实例的?_第4张图片

这里调用 sap.ui.model.type.Currency 的构造函数。

SAP UI5 xml 视图里定义的控件,运行时如何创建其实例的?_第5张图片

我们再回过头来看 xml 视图的加载和解析过程。

在 XMLView.js 的 this._xContent 字段里,我们能找到 xml 视图的字符串格式的源代码。

SAP UI5 xml 视图里定义的控件,运行时如何创建其实例的?_第6张图片

在 XMLView.js 里根据字符串 _xContent 进行搜索,即可查到这个字段赋值的位置:

SAP UI5 xml 视图里定义的控件,运行时如何创建其实例的?_第7张图片

在代码第 607 行触发 xml 视图文件的加载:

SAP UI5 xml 视图里定义的控件,运行时如何创建其实例的?_第8张图片

从方法名也能看出,xml 视图文件采用异步的方式进行加载:

loadResourceAsync(sResourceName).then(runPreprocessorsAsync).then(processView);

这里采用了 promise 异步编程模型:

        function loadResourceAsync(sResourceName) {
            return LoaderExtensions.loadResource(sResourceName, {async: true}).then(function(oData) {
                return oData.documentElement; // result is the document node
            });
        }

LoaderExtensions.loadResource 执行异步加载 xml 视图文件的任务,加载成功的结果,通过输入参数 oData 传递到匿名回调函数内。

进入 loadResource 内部:

SAP UI5 xml 视图里定义的控件,运行时如何创建其实例的?_第9张图片

转发给 sap.ui.loader._.getModuleContent(sResourceName, mOptions.url);

SAP UI5 xml 视图里定义的控件,运行时如何创建其实例的?_第10张图片
从缓存里读取。由于是第一次加载,缓存没有命中:

SAP UI5 xml 视图里定义的控件,运行时如何创建其实例的?_第11张图片

最终还是用的 jQuery.ajax api 去加载的数据:
SAP UI5 xml 视图里定义的控件,运行时如何创建其实例的?_第12张图片

加载成功后,调用 335 行的 success 回调函数:

SAP UI5 xml 视图里定义的控件,运行时如何创建其实例的?_第13张图片
ajax 请求的 dataType 字段值为 xml:

SAP UI5 xml 视图里定义的控件,运行时如何创建其实例的?_第14张图片
加载成功的 xml document 对象:

SAP UI5 xml 视图里定义的控件,运行时如何创建其实例的?_第15张图片

调用 resolve 方法,将 xml document 传给 promise api 的 then 回调函数。

SAP UI5 xml 视图里定义的控件,运行时如何创建其实例的?_第16张图片

此处就开始递归地解析 xml document 的节点了:

SAP UI5 xml 视图里定义的控件,运行时如何创建其实例的?_第17张图片

function parseChildren(xmlNode, bRoot, bIgnoreToplevelTextNodes, pRequireContext) {
            var children = xmlNode.childNodes;
            for (var i = 0; i < children.length; i++) {
                parseNode(children[i], bRoot, bIgnoreToplevelTextNodes, pRequireContext);
            }
        }

parseChildren 调用 parseNode.

更多Jerry的原创文章,尽在:"汪子熙":
SAP UI5 xml 视图里定义的控件,运行时如何创建其实例的?_第18张图片

你可能感兴趣的:(SAP UI5 xml 视图里定义的控件,运行时如何创建其实例的?)