天天看點

深入學習SAP UI5架構代碼系列之八:談談 SAP UI5 的視圖控件 ID,以及 SAP UI5 視圖和 Angular 視圖的異同

今天是 2021 年 4 月 27 日,周二,SAP 全球心理健康日。SAP 全球的員工,今天放假一天。

深入學習SAP UI5架構代碼系列之八:談談 SAP UI5 的視圖控件 ID,以及 SAP UI5 視圖和 Angular 視圖的異同

這不,早在上周五,我所在的 SAP Spartacus 開發團隊的開發經理,就貼心地在 Slack 上提醒所有組員,記得享受 “SAP Global Mental Health Day”.

深入學習SAP UI5架構代碼系列之八:談談 SAP UI5 的視圖控件 ID,以及 SAP UI5 視圖和 Angular 視圖的異同

關于 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控件的執行個體資料修改和讀取邏輯

(6) SAP UI5控件資料綁定的實作原理

(7) SAP UI5控件資料綁定的三種模式:One Way, Two Way和OneTime實作原理比較

本文繼續填坑。

在文章 一個用于SAP UI5學習的腳手架應用,沒有任何背景API的依賴 介紹的 SAP UI5 腳手架裡,建立一個 SAP UI5 Button 控件:

深入學習SAP UI5架構代碼系列之八:談談 SAP UI5 的視圖控件 ID,以及 SAP UI5 視圖和 Angular 視圖的異同

文章 SAP UI5 控件渲染機制 曾經提到,SAP UI5 控件擁有對應的渲染器,比如 Button 的渲染器叫做 ButtonRenderer,負責渲染出如下圖高亮的 HTML 代碼,其中控件 ID 為 __button0.

深入學習SAP UI5架構代碼系列之八:談談 SAP UI5 的視圖控件 ID,以及 SAP UI5 視圖和 Angular 視圖的異同

最近 Jerry 的技術交流群,有朋友問了我一個問題:如何使用原生的 JavaScript 代碼,觸發 SAP UI5 按鈕控件的點選事件處理函數?

深入學習SAP UI5架構代碼系列之八:談談 SAP UI5 的視圖控件 ID,以及 SAP UI5 視圖和 Angular 視圖的異同

我在這篇知乎文章如何使用原生的 JavaScript 代碼,觸發 SAP UI5 按鈕控件的點選事件處理函數裡,提供了解決方案:

深入學習SAP UI5架構代碼系列之八:談談 SAP UI5 的視圖控件 ID,以及 SAP UI5 視圖和 Angular 視圖的異同

在文章裡我開發了一個例子,三個 SAP UI5 Button 控件的 ID,在渲染出的 HTML 代碼裡分别為 __button0, __button1 和 __button2.

很容易看出 SAP UI5 控件 ID 的格式為:控件對應的名稱字首,再加上一個計數器。

其中控件字首名稱,例如 Button 控件 ID 的字首為 button, 該字首是 SAP UI5 控件中繼資料的一部分,在文章 深入學習SAP UI5架構代碼系列之四:SAP UI5控件的中繼資料實作 裡有詳細介紹。

深入學習SAP UI5架構代碼系列之八:談談 SAP UI5 的視圖控件 ID,以及 SAP UI5 視圖和 Angular 視圖的異同

而 SAP UI5 控件的全局計數器,維護在字典資料結構 mUIDCounts 裡,其中 key 為不同的 SAP UI5 控件中繼資料裡存儲的字首,value 為該類型的 SAP UI5 控件目前的計數器值。

深入學習SAP UI5架構代碼系列之八:談談 SAP UI5 的視圖控件 ID,以及 SAP UI5 視圖和 Angular 視圖的異同

迄今為止,我們讨論的都是開發人員在建立 SAP UI5 控件執行個體時,沒有顯式指定 ID 的情形。

如果開發人員通過構造函數 ID 參數,顯式傳入一個 ID:

深入學習SAP UI5架構代碼系列之八:談談 SAP UI5 的視圖控件 ID,以及 SAP UI5 視圖和 Angular 視圖的異同

則最後渲染出的 HTML 源代碼裡,ID 值不再包含字首:

深入學習SAP UI5架構代碼系列之八:談談 SAP UI5 的視圖控件 ID,以及 SAP UI5 視圖和 Angular 視圖的異同

這個邏輯在 SAP UI5 控件對應的原型鍊節點 ManagedObject 的構造函數裡可以清楚地看到:

如果開發人員顯式指定了控件 ID,則使用該 ID 渲染 HTML

如果開發人員沒有指定控件 ID,則使用控件中繼資料裡包含的字首,加上全局計數器自動生成 ID

深入學習SAP UI5架構代碼系列之八:談談 SAP UI5 的視圖控件 ID,以及 SAP UI5 視圖和 Angular 視圖的異同

SAP UI5 控件提供了一個工具方法,sap.ui.getCore().byId,能夠根據控件 ID,傳回對應的控件執行個體。

下面的代碼,assert 斷言語句能夠成功執行:

深入學習SAP UI5架構代碼系列之八:談談 SAP UI5 的視圖控件 ID,以及 SAP UI5 視圖和 Angular 視圖的異同

有的朋友可能會認為, byId 方法最終會交由原生的 DOM API document.getElementById 來執行,事實并非如此。

深入學習SAP UI5架構代碼系列之八:談談 SAP UI5 的視圖控件 ID,以及 SAP UI5 視圖和 Angular 視圖的異同

每個建立好的 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 後,會執行相應的處理邏輯。

深入學習SAP UI5架構代碼系列之八:談談 SAP UI5 的視圖控件 ID,以及 SAP UI5 視圖和 Angular 視圖的異同

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 視圖源代碼:

深入學習SAP UI5架構代碼系列之八:談談 SAP UI5 的視圖控件 ID,以及 SAP UI5 視圖和 Angular 視圖的異同

下圖是最終渲染出的在浏覽器裡觀測到的 HTML 源代碼,同上圖相比差異不大。

深入學習SAP UI5架構代碼系列之八:談談 SAP UI5 的視圖控件 ID,以及 SAP UI5 視圖和 Angular 視圖的異同

而 SAP UI5 XML 視圖,特别是引入 Fiori Elements 之後,XML 視圖的代碼同最後渲染出的 HTML 源代碼相比,差異巨大。因為渲染過程中,Fiori Elements 根據 SAP OData 上的 Annotation,進行了非常多複雜的處理,後續 Jerry 的公衆号會詳細介紹。

比如一個 SAP Fiori Elements 應用,隻用了 7 行代碼,定義了一個 Smart List:

深入學習SAP UI5架構代碼系列之八:談談 SAP UI5 的視圖控件 ID,以及 SAP UI5 視圖和 Angular 視圖的異同

最後得到一個包含 Filter Bar 的 Smart List:

深入學習SAP UI5架構代碼系列之八:談談 SAP UI5 的視圖控件 ID,以及 SAP UI5 視圖和 Angular 視圖的異同

Angular UI 不像 SAP UI5 那樣,傾向于為每一個 HTML 元素配置設定一個不重複的 ID. 下圖是 SAP UI5 的 HTML 源代碼,能觀察到不少 HTML 元素都有一個 Unique ID,而這種情形不會在 Angular 應用的 HTML 源代碼裡發生。

深入學習SAP UI5架構代碼系列之八:談談 SAP UI5 的視圖控件 ID,以及 SAP UI5 視圖和 Angular 視圖的異同

然而 Angular 有一個結構化指令 ng-template, 也具有通過 # 符号标注的 ID 屬性,配合另一個指令 NgIf,能實作頁面布局的條件渲染。下圖是一個具體例子:

深入學習SAP UI5架構代碼系列之八:談談 SAP UI5 的視圖控件 ID,以及 SAP UI5 視圖和 Angular 視圖的異同

SAP UI5 也有類似 Angular 這種 Template 設計,在 SAP UI5 裡稱為 ViewFragment. 在 SAP Fiori Elements 的架構實作裡,更是重度依賴了 ViewFragment,它能作為容器,将若幹邏輯上相關且具有重用可能性的 SAP UI5 控件包裹在一起,友善多個 XML 視圖重用。

Jerry 的後續文章會詳細介紹。

深入學習SAP UI5架構代碼系列之八:談談 SAP UI5 的視圖控件 ID,以及 SAP UI5 視圖和 Angular 視圖的異同

希望本文能幫助大家對 SAP UI5 控件 的 ID 屬性有一個更深入的認識,感謝閱讀。

更多閱讀

繼續閱讀