今天是 2021 年 4 月 27 日,週二,SAP 全球心理健康日。SAP 全球的員工,今天放假一天。前端
這不,早在上週五,我所在的 SAP Spartacus 開發團隊的開發經理,就貼心地在 Slack 上提醒全部組員,記得享受 "SAP Global Mental Health Day".程序員
關於 SAP 全球心理健康日的更多介紹,請參閱 SAP中國研究院官方公衆號這篇文章:SAP 全球心理健康日 | 爲員工提供精神充電的機會!瀏覽器
做爲一個程序員,在今天這一額外的假期裏,作點什麼好呢?我正好趁此機會,繼續書寫之前還沒有完成的一個 深刻學習 SAP UI5 框架代碼的系列文章。數據結構
(0) SAP UI5應用開發人員瞭解UI5框架代碼的意義架構
(1) SAP UI5 module懶加載機制框架
(2) SAP UI5 控件渲染機制函數
(3) HTML原生事件 VS SAP UI5 Semantic事件工具
(4) SAP UI5控件元數據的元數據實現佈局
(5) SAP UI5控件的實例數據修改和讀取邏輯學習
(7) SAP UI5控件數據綁定的三種模式:One Way, Two Way和OneTime實現原理比較
本文繼續填坑。
在文章 一個用於SAP UI5學習的腳手架應用,沒有任何後臺API的依賴 介紹的 SAP UI5 腳手架裏,建立一個 SAP UI5 Button 控件:
文章 SAP UI5 控件渲染機制 曾經提到,SAP UI5 控件擁有對應的渲染器,好比 Button 的渲染器叫作 ButtonRenderer,負責渲染出以下圖高亮的 HTML 代碼,其中控件 ID 爲 __button0.
最近 Jerry 的技術交流羣,有朋友問了我一個問題:如何使用原生的 JavaScript 代碼,觸發 SAP UI5 按鈕控件的點擊事件處理函數?
我在這篇知乎文章如何使用原生的 JavaScript 代碼,觸發 SAP UI5 按鈕控件的點擊事件處理函數裏,提供瞭解決方案:
在文章裏我開發了一個例子,三個 SAP UI5 Button 控件的 ID,在渲染出的 HTML 代碼裏分別爲 __button0, __button1 和 __button2.
很容易看出 SAP UI5 控件 ID 的格式爲:控件對應的名稱前綴,再加上一個計數器。
其中控件前綴名稱,例如 Button 控件 ID 的前綴爲 button, 該前綴是 SAP UI5 控件元數據的一部分,在文章 深刻學習SAP UI5框架代碼系列之四:SAP UI5控件的元數據實現 裏有詳細介紹。
而 SAP UI5 控件的全局計數器,維護在字典數據結構 mUIDCounts 裏,其中 key 爲不一樣的 SAP UI5 控件元數據裏存儲的前綴,value 爲該類型的 SAP UI5 控件當前的計數器值。
迄今爲止,咱們討論的都是開發人員在建立 SAP UI5 控件實例時,沒有顯式指定 ID 的情形。
若是開發人員經過構造函數 ID 參數,顯式傳入一個 ID:
則最後渲染出的 HTML 源代碼裏,ID 值再也不包含前綴:
這個邏輯在 SAP UI5 控件對應的原型鏈節點 ManagedObject 的構造函數裏能夠清楚地看到:
SAP UI5 控件提供了一個工具方法,sap.ui.getCore().byId,可以根據控件 ID,返回對應的控件實例。
下面的代碼,assert 斷言語句可以成功執行:
有的朋友可能會認爲, byId 方法最終會交由原生的 DOM API document.getElementById 來執行,事實並不是如此。
每一個建立好的 SAP UI5 控件實例,都會被添加到 SAP UI5 全局註冊表 mElements 中。隨後開發人員調用 sap.ui.getCore().byId 時,該方法直接從註冊表 mElements 中查詢並返回對應的控件實例便可,其效率高於原生 DOM API document.getElementById.
SAP UI5 的控件實例註冊過程,實如今 Core.prototype.registerElement 方法裏。下圖高亮的第 40705 行代碼拋出的錯誤消息,也解釋了爲何 SAP UI5 不容許兩個控件擁有相同的 ID. 方法 this.oConfiguration.getNoDuplicateIds 檢測到重複 ID 後,會執行相應的處理邏輯。
Angular 雖然和 SAP UI5 同樣,也是單頁面應用,而且兩者都容許並重度依賴自定義控件 (Angular 裏稱 Component),但兩者在視圖設計上一個較大的差別就是,Angular Component 的視圖實現於原生的 HTML 文件 (或者於內聯的 HTML 字符串) 裏,而非像 SAP UI5 那樣,使用 XML 或者 JavaScript 視圖來實現本身的頁面佈局。
所以,一個前端開發人員,僅憑靜態瀏覽 Angular Component 的 HTML 視圖源代碼,大體就能判斷出最後渲染而成的 HTML 頁面源代碼:兩者相差不大,Angular 沒有 SAP UI5 控件渲染器的概念。
例如,下圖是 SAP Commerce Cloud 組織架構明細頁面 (Organization Unit Detail) 的 HTML 視圖源代碼:
下圖是最終渲染出的在瀏覽器裏觀測到的 HTML 源代碼,同上圖相比差別不大。
而 SAP UI5 XML 視圖,特別是引入 Fiori Elements 以後,XML 視圖的代碼同最後渲染出的 HTML 源代碼相比,差別巨大。由於渲染過程當中,Fiori Elements 根據 SAP OData 上的 Annotation,進行了很是多複雜的處理,後續 Jerry 的公衆號會詳細介紹。
好比一個 SAP Fiori Elements 應用,只用了 7 行代碼,定義了一個 Smart List:
最後獲得一個包含 Filter Bar 的 Smart List:
Angular UI 不像 SAP UI5 那樣,傾向於爲每個 HTML 元素分配一個不重複的 ID. 下圖是 SAP UI5 的 HTML 源代碼,能觀察到很多 HTML 元素都有一個 Unique ID,而這種情形不會在 Angular 應用的 HTML 源代碼裏發生。
然而 Angular 有一個結構化指令 ng-template, 也具備經過 # 符號標註的 ID 屬性,配合另外一個指令 NgIf,能實現頁面佈局的條件渲染。下圖是一個具體例子:
SAP UI5 也有相似 Angular 這種 Template 設計,在 SAP UI5 裏稱爲 ViewFragment. 在 SAP Fiori Elements 的框架實現裏,更是重度依賴了 ViewFragment,它能做爲容器,將若干邏輯上相關且具備重用可能性的 SAP UI5 控件包裹在一塊兒,方便多個 XML 視圖重用。
Jerry 的後續文章會詳細介紹。
但願本文能幫助你們對 SAP UI5 控件 的 ID 屬性有一個更深刻的認識,感謝閱讀。
(2) SAP UI5 控件渲染機制
(3) HTML原生事件 VS SAP UI5 Semantic事件
(7) SAP UI5控件數據綁定的三種模式:One Way, Two Way和OneTime實現原理比較
更多Jerry的原創文章,盡在:"汪子熙":