深入掌握 SAP Fiori Elements 工作原理的前提條件:理解 Smart Field
SAP 前端開發(fā)者如今使用的 SAP Fiori Elements,在 2016 年時被稱為 Smart Template,其在 SAP 官網(wǎng)的定義是:
Smart Template 是一套框架,針對最常用的應用模式,根據(jù)元數(shù)據(jù)注解,加上預定義的模板,在運行時能夠動態(tài)生成 SAP UI 頁面。
原文:Smart templates provide a framework for generating UIs at runtime based on metadata annotations and predefined templates for the most used application patterns.
SAP 官網(wǎng)鏈接如下:
https://experience.sap.com/fiori-design-web/v1-36/smart-templates/
SAP Fiori Elements 的核心就是其基于的元數(shù)據(jù)注解,以及根據(jù)這些元數(shù)據(jù),在運行時 “智能地” 生成 UI 的能力。由于這種運行時動態(tài)生成 UI 的行為發(fā)生在幕后,對應用開發(fā)人員來說完全是一個黑盒子。不少開發(fā)人員覺得 SAP Fiori Elements 的工作原理很神秘,即使想研究其源代碼,也不知道該如何入手。
到 2021 年 5 月為止,SAP Fiori Elements 支持 5 種類型的預定義模板:
List report
Worklist
Object page
Overview page
Analytical list page
打開 List report 模板的 XML 視圖實現(xiàn)源代碼,能發(fā)現(xiàn) smartfield 和 smarttable 的使用:
二者都屬于 SAP Smart Controls,是構(gòu)成 SAP Fiori Elements 預定義模板的基石。
SAP 官網(wǎng)對 Smart Controls 的定義:一種特殊的 SAP UI5 控件集合,能夠通過解析 OData 元數(shù)據(jù),給普通的 SAP UI5 控件增添一些額外的功能。
要想搞清楚 SAP Fiori Elements 的工作原理,理解 Smart Controls 是前置條件之一。而 Smart Field 是 Smart Controls 大家庭中最簡單的類型,因此如果想研究 Smart Controls 的工作原理,Smart Field 是最佳的學習目標。
Jerry 開發(fā)了一個 Hello World 級別的 SAP UI5 應用,XML 視圖里僅僅包含一個 Smart Field.
應用的源代碼地址如下。
定義了 Smart Field 的 XML 視圖源代碼如下:
將該應用從 Github 代碼倉庫下載到本地,node loca.js 運行后,訪問如下 url,即可打開渲染后的頁面。
該應用渲染出來的頁面如下:
雖然我們在 XML 視圖里只定義了一個 Smart Field 控件,但最后渲染出的頁面里,居然包含了兩個輸入字段:
價格金額 (Amount)
價格的貨幣單位 (UnitCode)
另外,在 XML 視圖里我并未指定 Price 字段的標簽,那么最后界面里"Jerry的價格",到底是在哪里維護的呢?
這就是 Smart Controls 的神奇之處。
第 17 行 XML 視圖里的 smartField 標簽, id 屬性我硬編碼成 idPrice:
運行時,被 Smart Field 對應的 renderer,渲染成 div 標簽,id 為 __xmlview0–idPrice,這是我們在之前的兩篇文章里已經(jīng)了解過的內(nèi)容:
深入學習SAP UI5框架代碼系列之二:UI5 控件的渲染器
深入學習SAP UI5框架代碼系列之八:談談 SAP UI5 的視圖控件 ID,以及其和 Angular 視圖的異同
那么渲染出來的頁面里,另一個貨幣單位,即顯示 EUR 的字段,在 XML 視圖里根本沒有定義,它到底是根據(jù)什么樣的邏輯動態(tài)生成出來的?
既然前文已經(jīng)提到,Smart Field 的一大特征就是能夠解析 OData 元數(shù)據(jù),并為自身增添新的功能,所以我們回過頭仔細查看 XML 視圖里 smartField 綁定的屬性,其名稱為 Price.
在該項目的元數(shù)據(jù)定義文件,metadata.xml 里,我們找到了一些端倪:
第 10 行即是 XML 視圖里 smartField 綁定的 Price 屬性,如上圖紅色下劃線所示。該屬性具有一個命名空間為 sap 的注解,注解名稱為 unit,值為 CurrencyCode,意思是,該字段的單位,綁定到 OData 模型另一個名為 CurrencyCode 的字段,即上圖紅色箭頭指向的第 17 行的屬性。而我們在最終渲染頁面里看到的標簽"Jerry的價格",則通過另一個注解 sap:label 的值維護。
CurrencyCode 這個屬性本身,用注解 sap:semantics 聲明其語義為 currency-code.
如果把這個值修改一下,比如去掉中間的連接線,改成currencycode,則最后渲染出的頁面如下圖所示,貨幣單位字段將消失,說明 Smart Field 工作出了問題。
下面我們通過單步調(diào)試來搞清楚幕后到底發(fā)生了什么。
這是我使用的本地測試數(shù)據(jù):
在運行時,該數(shù)據(jù)成功加載后,在數(shù)據(jù)加載成功的 SAP UI5 框架回調(diào)函數(shù)里,調(diào)用 setElementBindingContext 函數(shù), 進而調(diào)用 propagateProperties 函數(shù),觸發(fā) Smart Field 的初始化處理邏輯。
注意觀察下圖右邊的調(diào)用棧,propagateProperties 會把控制權(quán)交給 SmartField.js, 后者調(diào)用工廠方法 _createFactory, 根據(jù)解析出的 OData 注解,即 sap: 開頭的注解,創(chuàng)建對應的普通 SAP UI5 控件實例。所謂普通的 SAP UI5 控件,即 sap.m 命名控件下的 UI5 控件。
XML 視圖里定義的元數(shù)據(jù)注解,通過工具 AnnotationHelper.getXXX 實現(xiàn)。
比如:
getUnit, 查找屬性上的 sap:unit 注解
getLabel, 查找屬性上的 sap:label 注解
以此類推
看到下圖 AnnotationHelper.js 里 isCurrency 方法里第 136 行硬編碼的 currency-code, 我們就能恍然大悟,明白為什么 XML 視圖里把 sap:semantics 的注解值從 currency-code 改成其他值之后,Smart Field 就無法正常工作的原因了。
AnnotationHelper.js 把一個 OData 屬性所有的注解解析完畢之后,交給ODataHelper,后者進行匯總,進行下一步處理。
下圖展示了 XML 視圖里關于 Price 和 CurrencyCode 兩個 OData 屬性,其元數(shù)據(jù)注解均已解析完畢。
最后,在 ODataControlFactory 這個工廠實現(xiàn)里,直接使用 JavaScript 關鍵字 new,新建一個普通的 sap.m.Input 控件實例,然后再由其渲染器生成原生的 HTML input 標簽。該標簽的 id 為 其父節(jié)點的 id 加上 -input 后綴。
下圖就是最后渲染而成的 input 標簽。
通過本文介紹的具體例子,我們能夠直觀地感受到,較之其在 XML 視圖里的定義相比,Smart Field 運行時能夠渲染出內(nèi)容豐富得多的頁面,而這些頁面,極度依賴于 Smart Field 綁定到的 OData 屬性上定義的以 sap: 作為前綴的元數(shù)據(jù)注解。
希望通過本文的介紹,大家對于 Smart Field 的工作原理和作用,能相比純粹閱讀 SAP 官網(wǎng)上的幫助文檔,有一個更深入的理解。后續(xù) Jerry 會繼續(xù)把 SAP Fiori Elements 涉及到的知識點,逐個剝離出來并分別用文章進行闡述,敬請期待。
HTML JavaScript web前端
版權(quán)聲明:本文內(nèi)容由網(wǎng)絡用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔相應法律責任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實的內(nèi)容,請聯(lián)系我們jiasou666@gmail.com 處理,核實后本網(wǎng)站將在24小時內(nèi)刪除侵權(quán)內(nèi)容。