聊聊 SAP 产品 UI 上的消息显示机制
這是 Jerry 2021 年的第 60 篇文章,也是汪子熙公眾號總共第 337 篇原創文章。
本文從 StackOverflow 社區上來自 Partner 的一個 SAP Commerce Cloud Spartacus UI 的定制化需求說起。
這個需求的背景是,客戶在 SAP 電商云的產品明細頁面,可以留下自己的評論,點擊 Submit 按鈕提交。
提交之后,能看到“謝謝評論”的提示消息。
客戶定制化需求是:不執行這個默認的消息顯示邏輯,即不顯示消息,而是執行其他邏輯,比如短信通知或郵件通知。
我們先簡單回顧 SAP 其他產品的 UI 消息顯示機制。
消息是應用程序執行過程中給用戶提供反饋的重要渠道之一,通常由用戶某個動作直接觸發,顯示在產品界面上。當然應用程序后臺作業運行到某個階段,在滿足指定條件時也能觸發消息顯示。簡明、清晰而準確的消息,能幫助用戶明確程序當前的運行狀況,指引其下一步的操作。
SAP 產品 UI 顯示的消息文本,均有專業的 Knowledge Management 即 KM 團隊負責審查和發布。
對于 SAP 開發人員來說,更關心的則是這些消息顯示的上下文;換言之,看到 UI 上顯示一條消息之后,能否在最短的時間內,高效定位到拋出該消息的準確代碼位置。
如下圖所示,在經典的 SAPGUI SE38 ABAP 程序編輯器,輸入一個不存在的報表名稱,會顯示一條消息:
Program XX does not exist.
其中 XX 是占位符,會被用戶實際輸入的報表名稱所替換。
基于 ABAP 實現的所有 SAP 產品,比如 SAP CRM,SAP SRM,SAP S/4HANA,SAP Cloud for Customer,UI 上顯示的每一條消息,在 ABAP 后臺均有一條對應的消息記錄,維護在事物碼 SE91 里。
以上圖的消息為例,其號碼為 DS017,其中 DS 為消息類別, 017 為消息編號,二者唯一確認一條消息記錄。
Jerry 之前的文章SAP 錯誤消息調試之七種武器:讓所有的錯誤消息都能被定位,曾經介紹過七種不同的方法,均能在 SAPGUI 環境里,已知消息類和消息編號,快速找到拋出該消息的準確位置。
到了 SAP CRM WebClient UI 里,瀏覽器上看到的每一條消息,比如下圖 Data Contains errors and cannot be saved, 仍然唯一對應后臺一條消息記錄 CRM_BUPA_BOL/036:
這條消息是由 Business Partner 應用負責維護的。
如何查找拋出 SAP WebClient UI 消息的對應后臺代碼位置,在 Jerry 的 SAP 社區博客上有介紹:
How to quickly locate the source code where a given message is raised in WebClient UI
到了 SAP Cloud for Customer,雖然 Partners 無法直接登錄 ABAP 后臺,然而仍然可以通過 Chrome 開發者工具,得到 UI 消息對應的 ABAP 后臺消息記錄的消息類和消息編號:
在 SAP Cloud for Customer 里,Partners 可以通過 Cloud Application Studio 新建 UI 消息:
在 ABSL 代碼里,通過 raise 語句顯示消息到 UI 上:
raise delivery_message.Create(“S”, this.OutboundDeliveryID);
運行時 delivery_message 定義的消息文本里的 &1,會被 this.outboundDeliveryID 字段的值取代。
到了 SAP S/4HANA 里,所有基于 Fiori Elements 創建的 Fiori 應用,共享同一套視圖模板和控制器實現,因此大多數消息不再由應用程序各自定義,而由框架統一維護。
比如下列 S/4HANA 物料主數據維護時的錯誤消息:
Product Type 03 is not valid:
這條消息維護于所謂的 Business Suite Foundation Reusable Components 開發包中的消息類 /BOFU/CODE_LISTS 內部。
我們再來分析本文開頭提到的 SAP Commerce Cloud 的消息顯示定制化需求。
“感謝評論”的消息文本 ID 為 productReview.thankYouForReview,在 ProductReviewEffects 接收到 POST_PRODUCT_REVIEW_SUCCESS 這個 Action 之后通過 MessageService 顯示到 UI 上。
一種最常規的二次開發思路就是,繼承 SAP Commerce Cloud UI 標準發布的 ProductReviewEffects 類,重載其接收到 POST_PRODUCT_REVIEW_SUCCESS 之后的實現代碼,將調用 MessageService 拋出感謝評論的代碼刪除掉即可。
然而 SAP Commerce Cloud UI 發布的所有 Effects 實現類都是不可擴展的,因此這條思路行不通。
Jerry 之前的文章:Jerry 在 2020 SAP全球技術大會的分享:SAP Spartacus 技術介紹的文字版,曾經介紹過 SAP 電商云 Spartacus UI,同 Commerce 后臺交互的邏輯:
當時我著重闡述的,是上圖右側紅色高亮區域的交互原理。
Spartacus 同 Commerce 系統的通信,通過 HTTP 協議調用 OCC API 完成。Connector 是 HTTP調用的發起者,維護了靜態的配置信息,即 API endpoint.
比如,從 Commerce 系統讀取產品主數據,讀取的字段列表以 url 參數的形式出現在 API endpoint 里。這些字段列表可以在 Connector 的靜態配置點里進行配置。
Connector 并不會直接同 Commerce 交互,而是把請求轉發給 Adapter,具體通信由 Adapter 完成,Connector 只負責調度 Adapter. Spartacus 發布的 Adapter 默認使用 OCC Module,即 Commerce 標準的 OCC Restful API,但是客戶也可以實現自己的 Adapter,連接 Commerce 之外的其他后臺系統。
Connector 將 Adapter 取回的數據交給 NgRx Store 結構統一管理,后者的復雜度被 Facade 層所隱藏,而Spartacus UI 組件只會同 Facade 層交互,進行數據綁定和頁面展示。這體現了關注點分離的設計原則。
再回到本文開頭客戶提出的定制化需求。為了實現該需求,我們需要深入了解下圖紅色高亮區域即 NgRx Store 和 SAP Spartacus Connector 交互的細節。
NgRx 是 Angular 基于 RxJs 的一個響應式狀態管理庫,包含下列核心概念,Jerry 會結合 SAP Commerce Cloud UI 對 NgRx 的實際使用情況來舉例說明。
- Action:其實就是編程領域的事件的別名。SAP Commerce Cloud UI 組件,能響應用戶操作,通過組件的 Service 實例,投遞出相應的 Action. Action 投遞方和 Action 接收方是解耦的,彼此感知不到對方。
下圖是 SAP 電商云產品明細頁面評論區域的 Submit 按鈕被點擊之后,對應的 Service 類拋出 PostProductReview Action 的代碼:
ProductActions.PostProductReview 是 NgRx Action 的一個子類,type 字段為 POST_PRODUCT_REVIEW,構造函數的參數 payload,定義了調用 Commerce OCC API 持久化用戶評論需要傳遞的數據結構:
- Effects:SAP Commerce Cloud UI Action 的接收方之一。下圖 Effects 代碼的語義是:接收類型為 POST_PRODUCT_REVIEW 的 Action(第46行),調用前文介紹的 Connector,向 Commerce 后臺發起 OCC API 調用(第49行),根據 API 返回結果,分別投遞評論保存成功或失敗的 Action:
PostProductReviewSuccess(第53行)
PostProductReviewFail(第56行)
-
Store:Angular 應用維護在內存中的存儲結構,存放了 SAP Commerce Cloud UI 所有組件的運行時數據。每當 Effects 調用 Commerce OCC API 拿到新的數據時,調用 Reducer,將增量數據填充到 Store 中去。
-
Reducer:本質上是一個有限狀態自動機,每當收到代表來自 Commerce 后臺的數據發生變化的 Action 時,狀態機驅動對應的 Reducer, 根據新的 Action 包含的負載,對 Store 中的數據進行調整。
例如產品明細頁面第一次渲染時,Effects 需要從 Commerce 后臺讀取所有的評論數據。讀取成功后,拋出 LOAD_PRODUCT_REVIEWS_SUCCESS Action. 下圖的 ProductReviewsReducer 接收到該 Action,從其 payload 中解析出實際評論數據并返回。這些返回的數據會被 NgRx 框架接收,并合并到 Store 中去。
- Selector:純函數,作為應用程序從 NgRx Store 中讀取最新數據的接口。
理清楚 SAP Commerce Cloud UI 使用 NgRx 進行狀態管理的細節之后,對于文章開頭的客戶定制化需求,也就不難實現了。
既然下圖所示的 SAP Commerce Cloud UI 標準的 Effects 無法擴展,我們注意到 UI 組件的 Service 層,才是所有事件流的起始點,因此可以實現新的 Service,來替換 SAP 電商云 UI 標準的 Service,然后基于該定制化 Service,實現配套的 Effects 和 Action.
如此一來,標準的和用戶評論相關的邏輯流(如下圖 1-2-3 所示)將不會再得到執行,取而代之的是我們自己定制化的執行流,如下圖 A-B-C 所示,其中藍色的圖例均為 Partners 需要開發的定制化代碼。
這個解決方案的簡要介紹:
(1) 創建新的 Action CustPostProductReview,CustPostProductReviewSuccess 和 CustPostProductReviewFail. 其實就是在標準的實現類之前,添加 Cust 的前綴。
(2) 創建新的 CustProductReviewService,繼承標準的 ProductReviewService. 重載其 add 方法,拋出新的 CustPostProductReview Action.
(3) 新建 CustProductReviewsEffects,接收新的 Action CUST_POST_PRODUCT_REVIEW(第25行),仍舊調用 Connector 將用戶評論持久化到 Commerce 后臺(第28行),然后拋出新的 Action CustPostProductReviewSucess.
自定義 Effect 接收到新的 Action CUST_POST_PRODUCT_REVIEW_SUCCESS 之后,就可以進行自定義邏輯編寫。
(4)將自定義的 Effect 和 Service 實現,通過 Angular 依賴注入框架,配置到對應的 Module 中。
本需求在 SAP Spartacus 3.1 版本測試通過。
更多閱讀
-
SAP UI5 OData謠言粉碎機:極短時間內發送兩個 Odata request, 前一個會自動被cancel 掉嗎
-
SAP UI5 和 Angular的函數防抖(Debounce)和函數節流(Throttle)實現原理介紹
-
SAP UI 渲染模式:客戶端渲染 VS 服務器端渲染
-
SAP UI 的加載動畫效果和幽靈設計(Ghost Design)
-
從一個實際的例子出發,談談 SAP Commerce Cloud 電商云的 UI 自定義開發
-
SAP Commerce Cloud (電商云) UI 的懶加載功能
-
SAP CRM Fiori 應用和 SAP Commerce Cloud (電商云) UI 如何通過調整 CSS 來改變UI 顯示風格
-
SAP 產品一脈相承的 UI 增強思路,在 SAP Commerce Cloud(電商云) UI 增強實現中的體現
-
深入學習 SAP UI5 框架代碼系列之八:談談 SAP UI5 的視圖控件 ID,以及其和 Angular 視圖的異同
-
對 SAP UI5 一無所知的新手,從哪些材料開始學習比較好?
-
響應式編程在 SAP 標準產品 UI 開發中的一個實踐
-
如何在 SAP UI5 應用中集成第三方庫 :一個在移動設備上查看 Web 應用打印調試信息的小技巧
-
SAP Commerce Cloud UI 的用戶會話管理
-
關于 SAP 產品 UI 的搜索引擎優化 SEO - Search Engine Optimization
-
談談 SAP 產品 UI 開發中的組件概念
更多Jerry的原創文章,盡在:“汪子熙”:
總結
以上是生活随笔為你收集整理的聊聊 SAP 产品 UI 上的消息显示机制的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: egret白鹭 基于eui组件的一些动画
- 下一篇: dedecms织梦后台账号或密码忘记了怎