天天看點

SAP Fiori Elements List Report Smart Table 列項目寬度計算的奧妙

這是 Jerry 2021 年的第 36 篇文章,也是汪子熙公衆号總共第 312 篇原創文章。

Jerry 之前寫的 SAP Fiori Elements 系列文章:

SAP Fiori Elements List Report Smart Table 列項目寬度計算的奧妙

關于 List Report 模闆裡 Smart Table 控件裡不同列項目的寬度問題,也有很多朋友私下裡問我:

SAP Fiori Elements List Report Smart Table 列項目寬度計算的奧妙

控件的空間,在傳統開發上,我們可以操控 column 的 width 屬性。但是在Fiori Elements 開發中并沒有碰到相應的參數。 請問您知道我可以通過什麼參數控制嘛?”

SAP Fiori Elements List Report Smart Table 列項目寬度計算的奧妙
SAP Fiori Elements List Report Smart Table 列項目寬度計算的奧妙

因為我日常工作用的是 Angular 而非 SAP Fiori Elements,是以這些問題隻有業餘時間研究。此類問題我通常的做法是,在設法尋找解決方案之前 (如何通過代碼調整 Smart Table 列項目的寬度),先做一些調研,搞清楚目前行為的實作原理。這樣下次遇到新的列項目寬度的相關需求,之前調研學到的知識說不定能夠重用。

Jerry 之前的文章 SAP Fiori Elements 架構裡 Smart Table 控件的工作原理介紹,向大家揭秘了 Smart Table 控件裡的列項目,來自 OData 中繼資料裡擁有 com.sap.vocabiularies.UI.LineItem 注解的模型字段。但是當時我們沒有關于列項目的寬度 (width) 進行讨論。

在 Chrome 開發者工具裡,檢視任意兩個列項目的寬度,發現機關均為 rem:

SAP Fiori Elements List Report Smart Table 列項目寬度計算的奧妙
SAP Fiori Elements List Report Smart Table 列項目寬度計算的奧妙

px, em 和 rem 都是 css 的長度機關,其中 px 即像素,相對于顯示器螢幕分辨率而言,在網際網路早期應用裡使用得比較多。而 em 和 rem 是相對長度機關,前者相對于其父元素,後者相對于文檔根元素,在響應式頁面設計裡廣泛使用。

通過 Jerry 之前這篇文章 Jerry的Fiori原創文章合集 裡介紹的調試技巧,我成功找到了 Smart Table 運作時計算列項目寬度的代碼位置。簡言之,Fiori Elements List Report 模闆裡 Smart Table 每個列項目的初始寬度,同樣取決于其 OData 中繼資料。

打開 Chrome 開發者工具,切換到 Sources 标簽頁,快捷鍵 Ctrl + O,在彈出對話框裡輸入 SmartTable,這樣可以快速打開其實作檔案 SmartTable.js:

SAP Fiori Elements List Report Smart Table 列項目寬度計算的奧妙

該檔案第 3817 行,_calcCoumnWidth 函數, 即 Smart Table 列項目寬度的計算實作源代碼

SAP Fiori Elements List Report Smart Table 列項目寬度計算的奧妙

從源代碼裡的注釋可知,Fiori Elements 基于 OData 中繼資料裡的屬性來計算列項目的寬度 (Calculates the column width from the metadata attributes).

The optimal column width is calculated with creating the longest possible sample of the created model type.

根據模型字段的類型,構造出該類型允許的最長内容的例子資料,即可計算出該列理論上的寬度。

計算列項目寬度函數 calcCoumnWidth 的輸入參數:

oField:該列項目字段的 OData 中繼資料

bAdditionalProperty:boolean 類型,表明計算寬度時,除了字段 OData 中繼資料本身,是否還需要考慮其他因素

mConfig:計算寬度時使用的配置項,包含寬度的最大,最小值,預設值和其他配置标志位

這個函數實作代碼裡資訊量很大:

SAP Fiori Elements List Report Smart Table 列項目寬度計算的奧妙

計算寬度使用的配置對象,mConfig 的值,是在代碼裡以近似寫死的方式填充的。從上圖能夠看出,Fiori Elements Smart Table 的列項目寬度,最大值為 19;如果計算時不考慮額外屬性,最小寬度值為 2,否則為 1;如果 OData 中繼資料裡提供的屬性,不足以計算出一個合适的寬度值,則使用代碼第 3822 行維護的預設寬度:在考慮額外屬性情況下,預設寬度為 4,否則為 8;機關為 rem.

接下來為計算列項目寬度做準備。

第 3833 行的字元 w, 是為了針對字段中繼資料類型為 Edm.String, 即字元串類型的列項目做準備的。此類型字段,在中繼資料裡還有另一個屬性 MaxLength, 即字元串最大長度。

SAP Fiori Elements List Report Smart Table 列項目寬度計算的奧妙

例如一個 MaxLength 為 40 的字元串類型字段,Smart Table 計算其寬度的邏輯就是,運作時生成一個由 40 個 w 字元組成的字元串,計算其渲染出來後占據的寬度,将該寬度值作為此列項目最終顯示在界面上的寬度。

字段類型不同,其理論上最長的可能值也不同。比如上圖第 3842 行開始的代碼提到,類型 Edm.Int16, 理論的最長值為 32768, 占據 5 個字元的位置;Edm.Int32 則理論最多占據 9 個字元位,因為其最大值為 2147483648. 依次類推。

下圖的 4 個 IF-ELSE 分支,分别對應着類型為 Byte, Time, Boolean 和 String 字段的寬度計算。下面我們來了解最簡單的字元串類型的列項目寬度計算邏輯。

SAP Fiori Elements List Report Smart Table 列項目寬度計算的奧妙

下圖三個标号處的主要邏輯:字段 MainProductCategory, 類型為 Edm.String, 最大長度為 40 個字元,是以标号 3 處,将變量 sChar 代表的字元 w,重複 40 次後生成一個新的字元串,然後調用函數 measureText, 計算該字元串渲染出來的寬度。

SAP Fiori Elements List Report Smart Table 列項目寬度計算的奧妙

在 measureText 函數内部,第 3792 行動态建立一個 canvas 标簽,該标簽常用于 JavaScript 動态繪制圖形的場景。拿到 canvas 的 2d 上下文後,調用其原生 API,measureText,得到在該 canvas 上渲染長度為 40 的字元串需要占據的寬度,機關為 px,最後再除以 baseFontSize, 換算成 rem 機關。

SAP Fiori Elements List Report Smart Table 列項目寬度計算的奧妙

計算出來的列項目寬度,會存儲在 column 對象執行個體裡,并在最終的 HTML 代碼渲染過程裡,交給 TableRenderer 進行 width 渲染。這就是我們在本文開始的 Chrome 開發者工具裡,觀察到 HTML 源代碼裡 th 元素的 CSS style 面闆裡的 width 屬性。

SAP Fiori Elements List Report Smart Table 列項目寬度計算的奧妙

至此,本文介紹了 SAP Fiori Elements List Report Smart Table 列項目的初始寬度計算邏輯。從以上邏輯大家不難發現,寬度計算是根據字段中繼資料的 MaxLength 屬性,而不是運作時該字段實際的顯示值,因而會出現某些朋友抱怨的“雖然某列顯示的内容很少,但還是占據了很寬的空間,導緻螢幕空間使用率不夠"的問題, 如下圖所示:

SAP Fiori Elements List Report Smart Table 列項目寬度計算的奧妙

另外,我們點選 Settings 按鈕進行個性化設定:

SAP Fiori Elements List Report Smart Table 列項目寬度計算的奧妙

讓 Smart Table 運作時隻顯示兩列:

SAP Fiori Elements List Report Smart Table 列項目寬度計算的奧妙

之後顯示的頁面,确實隻包含我們在個性化設定裡選擇的 Image 和 Product 兩列,然而它們的寬度,和個性化之前相比并未發生變化,是以頁面非常難看:

SAP Fiori Elements List Report Smart Table 列項目寬度計算的奧妙

Jerry 後續的 SAP Fiori Elements 系列文章,會介紹如何解決這個寬度沒能夠動态更新的問題,敬請期待。

SAP Fiori Elements List Report Smart Table 列項目寬度計算的奧妙
SAP Fiori Elements List Report Smart Table 列項目寬度計算的奧妙

繼續閱讀