深刻掌握 SAP Fiori Elements 工做原理的前提條件:理解 Smart Field

這是 Jerry 2021 年的第 33 篇文章,也是汪子熙公衆號總共第 309 篇原創文章。前端

SAP 前端開發者現在使用的 SAP Fiori Elements,在 2016 年時被稱爲 Smart Template,其在 SAP 官網的定義是:node

Smart Template 是一套框架,針對最經常使用的應用模式,根據元數據註解,加上預約義的模板,在運行時可以動態生成 SAP UI 頁面。git

原文:Smart templates provide a framework for generating UIs at runtime based on metadata annotations and predefined templates for the most used application patterns.github

SAP 官網連接以下:web

https://experience.sap.com/fi...服務器

SAP Fiori Elements 的核心就是其基於的元數據註解,以及根據這些元數據,在運行時 "智能地" 生成 UI 的能力。因爲這種運行時動態生成 UI 的行爲發生在幕後,對應用開發人員來講徹底是一個黑盒子。很多開發人員以爲 SAP Fiori Elements 的工做原理很神祕,即便想研究其源代碼,也不知道該如何入手。app

到 2021 年 5 月爲止,SAP Fiori Elements 支持 5 種類型的預約義模板:框架

  • List report
  • Worklist
  • Object page
  • Overview page
  • Analytical list page

打開 List report 模板的 XML 視圖實現源代碼,能發現 smartfield 和 smarttable 的使用:webapp

兩者都屬於 SAP Smart Controls,是構成 SAP Fiori Elements 預約義模板的基石。ide

SAP 官網對 Smart Controls 的定義:一種特殊的 SAP UI5 控件集合,可以經過解析 OData 元數據,給普通的 SAP UI5 控件增添一些額外的功能。

要想搞清楚 SAP Fiori Elements 的工做原理,理解 Smart Controls 是前置條件之一。而 Smart Field 是 Smart Controls 你們庭中最簡單的類型,所以若是想研究 Smart Controls 的工做原理,Smart Field 是最佳的學習目標。

Jerry 開發了一個 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,這是咱們在以前的兩篇文章裏已經瞭解過的內容:

那麼渲染出來的頁面裏,另外一個貨幣單位,即顯示 EUR 的字段,在 XML 視圖裏根本沒有定義,它究竟是根據什麼樣的邏輯動態生成出來的?

既然前文已經提到,Smart Field 的一大特徵就是可以解析 OData 元數據,併爲自身增添新的功能,因此咱們回過頭仔細查看 XML 視圖裏 smartField 綁定的屬性,其名稱爲 Price.

在該項目的元數據定義文件,metadata.xml 裏,咱們找到了一些端倪:

第 10 行便是 XML 視圖裏 smartField 綁定的 Price 屬性,如上圖紅色下劃線所示。該屬性具備一個命名空間爲 sap 的註解,註解名稱爲 unit,值爲 CurrencyCode,意思是,該字段的單位,綁定到 OData 模型另外一個名爲 CurrencyCode 的字段,即上圖紅色箭頭指向的第 17 行的屬性。而咱們在最終渲染頁面裏看到的標籤"Jerry的價格",則經過另外一個註解 sap:label 的值維護。

CurrencyCode 這個屬性自己,用註解 sap:semantics 聲明其語義爲 currency-code.

若是把這個值修改一下,好比去掉中間的鏈接線,改爲currencycode,則最後渲染出的頁面以下圖所示,貨幣單位字段將消失,說明 Smart Field 工做出了問題。

下面咱們經過單步調試來搞清楚幕後到底發生了什麼。

這是我使用的本地測試數據:

在運行時,該數據成功加載後,在數據加載成功的 SAP UI5 框架回調函數裏,調用 setElementBindingContext 函數, 進而調用 propagateProperties 函數,觸發 Smart Field 的初始化處理邏輯。

注意觀察下圖右邊的調用棧,propagateProperties 會把控制權交給 SmartField.js, 後者調用工廠方法 _createFactory, 根據解析出的 OData 註解,即 sap: 開頭的註解,建立對應的普通 SAP UI5 控件實例。所謂普通的 SAP UI5 控件,即 sap.m 命名控件下的 UI5 控件。

XML 視圖裏定義的元數據註解,經過工具 AnnotationHelper.getXXX 實現。
好比:

  • 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 屬性,其元數據註解均已解析完畢。

最後,在 ODataControlFactory 這個工廠實現裏,直接使用 JavaScript 關鍵字 new,新建一個普通的 sap.m.Input 控件實例,而後再由其渲染器生成原生的 HTML input 標籤。該標籤的 id 爲 其父節點的 id 加上 -input 後綴。

下圖就是最後渲染而成的 input 標籤。

經過本文介紹的具體例子,咱們可以直觀地感覺到,較之其在 XML 視圖裏的定義相比,Smart Field 運行時可以渲染出內容豐富得多的頁面,而這些頁面,極度依賴於 Smart Field 綁定到的 OData 屬性上定義的以 sap: 做爲前綴的元數據註解。

但願經過本文的介紹,你們對於 Smart Field 的工做原理和做用,能相比純粹閱讀 SAP 官網上的幫助文檔,有一個更深刻的理解。後續 Jerry 會繼續把 SAP Fiori Elements 涉及到的知識點,逐個剝離出來並分別用文章進行闡述,敬請期待。

更多閱讀

更多Jerry的原創文章,盡在:"汪子熙":

相關文章
相關標籤/搜索