這是 Jerry 2021 年的第 33 篇文章,也是汪子熙公衆号總共第 309 篇原創文章。
Jerry 的日常工作内容從 2020 年 8 月轉到 Angular 前端開發之後,算是領略到了這個流行前端架構繁榮生态圈的風采:在開發過程中遇到 Angular 技術問題時,很容易在社群裡找到大量相關文章。除了每天我都要浏覽的 Angular 官網之外,我也經常閱讀一些國内外大神寫的關于 Angular 源代碼分析的部落格。
同 Angular 相比,使用 SAP Fiori Elements 的從業者的絕對人數沒有 Angular 多,除了 SAP 官網文檔之外,介紹 Fiori Elements 源代碼實作和工作原理的文章不多,中文材料就更少了。
是以 Jerry 試着用中文寫了一些 SAP Fiori Elements 使用和工作原理介紹的文章,希望對這個開發架構的中文生态圈貢獻一點微薄之力:
在沒有任何前端開發經驗的基礎上, 建立第一個 SAP Fiori Elements 應用
答網友提問:使用 SAP Fiori Tools 建立的 Fiori Elements 應用,如何進行二次開發?
本地開發好的 SAP Fiori Elements 應用,如何部署到 ABAP 伺服器上
深入掌握 SAP Fiori Elements 工作原理的前提條件:了解 Smart Field
本文繼續通過 SAP Fiori Elements 應用一個實際增強的例子,來闡述其工作原理。
Jerry 上述列舉的文章,介紹了如何基于 SAP ES5 Demo 系統上部署的一個 OData 服務,建立一個類型為 List Report 的 SAP Fiori Elements 應用。其界面如下:
其中表格區域的工具欄裡,黑色高亮框内為 Fiori Elements 表格控件自帶的按鈕,提供了表格行項目的複制,建立,删除等功能。而紅色的按鈕則是我通過 Fiori Elements 應用增強的方式繪制出來的。
本文我們會分享:如何在 SAP Fiori Elements 表格控件的工具欄裡,添加新的自定義按鈕。
本系列後續文章,Jerry 會介紹,如何在自定義按鈕的點選事件處理函數裡,用代碼取得目前選中行項目的明細資訊。
Jerry 之前的文章 答網友提問:使用 SAP Fiori Tools 建立的 Fiori Elements 應用,如何進行二次開發?,曾經提到了在 Fiori Elements 項目工程的 manifest.json 檔案裡,通過聲明并實作 sap.ui.controllerExtensions 的方式來進行二次開發。sap.ui.controllerExtensions 可以了解成 ABAP 裡的 BAdI definition,而我們基于 sap.ui.controllerExtensions 建立的自定義控制器 (controller.js), 則可類比成 ABAP BAdI 增強的具體實作。
在 manifest.json 的 extends 區域裡維護如下代碼:
上述代碼的關鍵點解釋:
為該項目聲明一個 sap.ui.controllerExtension 的實作,其源代碼位于我們建立的控制器裡。
聲明自定義控制器的 id,稍後我們會手動建立這個控制器:com.sap.jerry.jerryfioriapp.ext.controller.ListReportExtension.
聲明這個自定義控制器工作的 OData EntitySet 名稱。
聲明按鈕明細,在 SAP Fiori Elements 裡按鈕實作的模型稱為 Action.
上圖聲明了自定義 Action 的若幹屬性:
id 屬性值,最後會作為渲染出的 HTML 原生代碼中 button 标簽 id 值的一部分。
text 屬性值,即 UI 顯示按鈕的标簽值。
press 屬性值即該按鈕的點選處理函數的名稱,我們稍後需要在自定義控制器裡實作一個同名函數。
requiresSelection 屬性,顧名思義,如果為 true,表明該按鈕隻有當表格某行項目被選中時才能夠被點選。例如下圖所示,表格區域沒有任何一行被選中,此時我的自定義按鈕,處于不可點選狀态。
manifest.json 裡的增強定義完畢後,接着我們建立一個控制器 ListReportExtension.controller.js,在這個檔案裡編寫 manifest.json 裡聲明的函數,即按鈕點選事件處理函數
onCustomAction1
目前,點選自定義按鈕後,隻是彈出一個對話框而已:
如上圖所示,點選自定義按鈕之後,看到了期望的彈出框。我們再修改按鈕的屬性,進行一些額外的測試。
給自定義按鈕添加一個 global 為 true 的屬性:
重新打開頁面,發現該按鈕跑到應用右上方,成為一個全局按鈕了。
想知道我是如何知道 global,determining 這些屬性的名稱嗎?答案是閱讀 SAP Fiori Elements XML 視圖的源代碼實作。
Jerry 之前的文章 在沒有任何前端開發經驗的基礎上, 建立第一個 SAP Fiori Elements 應用 曾經提到,SAP Fiori Elements 預置了很多頁面模闆:
List Report Object Page
Worklist
Analytical List Page
Overview Page
這些頁面模闆的布局,均采取 XML 視圖實作。
以調試模式啟動 SAP Fiori Elements 應用,即可在 Chrome 開發者工具 network 标簽頁裡,觀察到這些 XML 視圖的加載:
上面這張圖資訊量很大。首先左邊清單裡,紅色高亮的 ListReport.view.xml, 當然就是 List Report 模闆的 XML 視圖實作了。這個 XML 視圖實作裡包含了兩個頁面片段 (fragment),即上圖右邊标号為 1 和 2 的元素:
FullscreenPage.fragment.xml
CreateWithDialog.xml
一個頁面片段又可以包含若幹個頁面片段。換言之,List Report (以及 SAP Fiori Elements 的其他頁面模闆) 的 XML 視圖實作,是以 ListReport.view.xml 為根節點的一棵樹狀結構,葉節點為不同的頁面片段。
上圖不同高亮顔色的頁面片段,均和 SAP Fiori Elements 自定義按鈕的渲染相關,繪制成樹狀結構如下:
箭頭符号表示包含關系,比如 SmartTable.fragment.xml 源代碼裡,包含了名為 SmartTableToolbar 的視圖檔段。
為什麼本文之前提到的在 manifest.json 裡添加的 determining = true 的自定義按鈕,會出現在 List Report 的 footer 區域?答案就在 FullscreenPage 頁面片段的源代碼裡。
如上圖所示,在綠色的 footer 标簽裡,使用 XML 視圖指令,template:repeat ,周遊綁定到該頁面片段的 Actions 結構,将結構裡每一個元素,賦給模闆變量 customaction, 該變量此時包含的就是 manifest.json extends 區域裡聲明的自定義按鈕的明細。 然後用另一個模闆指令,template:if, 判斷目前自定義按鈕的屬性,如果 determining 屬性為 true,且 global 屬性為 false,則在目前區域即 footer 區域渲染該自定義按鈕。
是以最後在 footer 區域渲染的自定義按鈕效果如下:
而 List Report 表格的工具欄區域的按鈕,實作在頁面片段 BreakoutActions.fragment.xml 裡:
第 7 行的注釋寫得很清楚了,使用 template: if 指令,判斷下列布爾表達式的值:
!KaTeX parse error: Expected 'EOF', got '&' at position 28: …n>determining} &̲& !{customaction>global}
如果表達式的值為 true,則渲染被 template: if 包裹的 button 元素。
上圖 template:if, 是 SAP UI5 針對 XML 視圖實作的自定義指令,在需要滿足根據某種判斷條件來顯示或隐藏 UI 元素此類需求時特别有用。其效果和使用方式,和 Angular 裡的結構型指令 ngIf 非常類似。
比如下圖是SAP Commerce Cloud (Spartacus UI) Organization Unit 明細頁面視圖實作的部分截圖,54 行的 div 标簽上,施加了一個 ngIf 指令,配置設定的布爾表達式是 model.approvalProcess.name, 語義是:當且僅當 model.approvalProcess.name 的值不為空時,才渲染這個 div 标簽及其子元素。
最後一個問題:例如 BreakoutActions 頁面片段裡,UI5 自定義指令綁定的這些 Actions 模型,資料來自哪裡?
當然是來自 Fiori Elements 工程裡的 manifest.json 檔案裡定義的同名屬性 Actions:
在 SAP Fiori Elements 應用啟動時,manifest.json 檔案會被架構代碼 Component.js 的 loadManifests 方法加載,其文本内容會被反序列化成 JSON 對象:
manifest.json 檔案的 Actions 區域的内容,會被綁定到 List Report 相關的頁面片段裡,參與各種自定義指令 template: xxx 的執行流程中。
希望通過本文的介紹,大家對于 SAP Fiori Elements List Report 裡自定義按鈕的渲染邏輯,能夠有進一步的了解。
本系列後續文章,Jerry 會介紹,如何讓 SAP Fiori Elements 應用表格區域裡,選中的行項目的明細資訊,包含在自定義按鈕點選後顯示的彈出對話框裡。敬請期待。
更多閱讀