深入學習SAP UI5框架程式碼系列之六:SAP UI5控制元件資料繫結的實現原理
這是Jerry 2021年的第 7 篇文章,也是汪子熙公眾號總共第 278 篇原創文章。
系列目錄
(0) SAP UI5應用開發人員瞭解UI5框架程式碼的意義
(2) SAP UI5 控制元件渲染機制
(3) HTML原生事件 VS SAP UI5 Semantic事件
(6) SAP UI5控制元件資料繫結的實現原理(本文)
(7) SAP UI5控制元件資料繫結的三種模式:One Way,Two Way和OneTime實現原理比較
(8) SAP UI5控制元件ID的生成邏輯
(9) SAP UI5控制元件的多語言(國際化,Internationalization,i18n)支援的實現原理
(10) XML檢視裡的button控制元件
(11) button控制元件和它背後的DOM元素
Jerry使用Angular做開發已經有幾個月了,其間也學習了Angular控制元件的資料繫結,再回過頭來重溫SAP UI5控制元件資料繫結,別有一番味道。
之前Jerry時不時會在微信上收到一些朋友的諮詢,諸如:“我的SAP UI5控制元件做了繫結,從Chrome開發者工具也能看到後臺返回的OData API確實包含了資料,但是UI5頁面渲染出來之後,為什麼控制元件上沒有顯示繫結的資料呢?”此類問題。
其實,如果瞭解一些SAP UI5控制元件的資料繫結實現細節,此類問題完全可以透過自己除錯的方式去排錯。
我們還是使用之前文章 一個用於SAP UI5學習的腳手架應用,沒有任何後臺API的依賴 提到的腳手架應用來學習。
新增下列五行高亮程式碼:
建立一個新的JSON模型,包含一個欄位field_for_text, 值為Jerry,再將該模型繫結到button控制元件,模型欄位field_for_text繫結到button的text屬性。
這樣一來,執行時看到按鈕的標籤就成了field_for_text的值"Jerry",而不是第18行給text屬性賦予的硬編碼值"Button":
本文的目的就是,闡述清楚第一張圖高亮的五行程式碼,背後發生了什麼事情。
var oModel = new sap.ui.model.json.JSONModel();
當這行程式碼執行之後,JSONModel以及包含對應的模型繫結實現邏輯的JavaScript原始檔會自動被載入,這體現了SAP UI5 Module的懶載入特性,在本系列這篇文章裡介紹過: 深入學習SAP UI5框架程式碼系列之一:UI5 Module的懶載入機制。
本系列之前的文章,我們曾經多次提及SAP UI5控制元件的原型繼承鏈:
Button -> Control -> Element -> ManagedObject
-> EventProvider -> BaseObject
本文我們會學習到另一條原型繼承鏈:
JSONModel -> ClientModel -> Model -> MessageProcessor -> EventProvider -> BaseObject
從上圖第61行的建構函式的輸入引數oData,不難發現,在UI5應用裡建立JSONModel例項時,可以將模型儲存的資料一併指定。
這樣,我們之前腳手架應用裡的程式碼,可以精簡成下圖右邊所示:
單步除錯JSONModel的建構函式,會發現它依次會呼叫原型繼承鏈上游節點的ClientModel,Model和MessageProcessor的建構函式。
下圖是Model建構函式的實現,資訊量很大:
(1) 第69行,說明SAP UI5模型繫結的預設方式是雙向繫結;
(2) 第83行,說明SAP UI5模型繫結支援單向,雙向和單次繫結。本系列下一篇文章 SAP UI5控制元件資料繫結的三種模式:One Way,Two Way和OneTime實現原理比較 會介紹這三種方式的區別。
oModel.setData(myData);
將一個JSON物件透過setData傳入JSONModel例項。
setData方法有一個可選引數bMerge,如果顯式指定為true,則會呼叫下圖88行的jQuery.extend, 將本地傳入的JSON物件同JSONModel原有的資料進行合併(merge). 因為我們本例呼叫setData並未指定該引數,所以不進行合併,直接執行95行的checkUpdate:
因為此時UI5 button控制元件例項尚未同JSONModel例項建立繫結關係,所以模型的aBindings陣列為空,因此checkUpdate實際並未執行任何和控制元件繫結相關的操作,直接返回。
oButton1.setModel(oModel);
這行語句的作用,就是將控制元件例項和傳入方法的JSONModel例項建立繫結關係。
- 4597~4604:該IF分支處理UI5控制元件之前已經繫結到某個模型例項的情況,此時使用delete操作,刪除原有的模型引用,然後更新繫結資訊。而本例是button控制元件第一次呼叫setModel,故不會進入此IF分支。
- 4607:UI5控制元件維護了一個類似字典的鍵值對資料結構,key為模型名稱,value為模型例項。從此處的SAP UI5原始碼實現不難得出結論,UI5控制元件支援同時繫結到多個模型例項上,只要該控制元件在呼叫setModel方法時,給傳入的模型例項透過方法第二個引數sName,賦予不同的模型名稱即可。
至此,JSONModel例項的field_for_text欄位值,還不會自動流向button控制元件的text屬性,直到下面這行程式碼的執行。
oButton1.bindProperty(“text”, “/field_for_text”);
該方法首先構造了一個包含JSONModel繫結欄位的物件oBindingInfo:
將該oBindingInfo維護到控制元件的中央繫結資訊儲存資料結構mBindingInfos裡,該資料結構同樣是一個鍵值對,key為控制元件屬性,本例為text,值為oBindingInfo物件,物件裡包含了text屬性繫結到JSONModel例項的欄位名稱:field_for_text.
單步除錯進入上圖3347行的_bindProperty方法:
3417行,呼叫JSONModel的bindProperty方法,生成oBinding物件:
這裡再次出現了關於SAP UI5資料繫結的三種模式處理的原始碼,本系列後續文章會專門介紹。
3433行將生成的oBinding物件例項,新增到aBindings陣列裡。
那麼oBinding例項是如何生成的?需要單步除錯上圖3417行的oModel.bindProperty程式碼。
JSONModel.bindProperty的實現,就是一個單純的new呼叫。不過更重要的是,此處我們瞭解到了另一條原型繼承鏈:
JSONPropertyBinding -> ClientPropertyBinding -> PropertyBinding -> Binding -> EventProvider -> BaseObject
我們注意到,在oBinding例項裡,有個欄位叫做oValue, 其值正好是JSONModel例項維護的JSON物件欄位field_for_text的值Jerry. 實際上,最後button控制元件的text屬性,顯示的值正是oBinding例項oValue欄位的值。
所以需要搞清楚this.oValue的賦值邏輯,就得單步執行上圖第35行的this._getValue方法。
this._getValue()
該函式負責將field_for_text欄位的值,從this.oModel.oData.field_for_text欄位中提取出來,如下圖所示:
一旦this._getValue執行完之後,控制元件text屬性同JSONModel例項的field_for_text欄位就成功建立起繫結關係,之後我們就能直接從控制元件例項變數oButton1出發,去找到其text屬性應該顯示的值:
希望透過本文的介紹,能讓大家對SAP UI5控制元件資料繫結的實現原理有一個最基本的瞭解。
如果遇到控制元件繫結不能按照自己的期望工作的時候,不妨試試按照本文提到的這些關鍵點去除錯。
本系列下一篇文章,會介紹SAP UI5控制元件資料繫結的三種模式:One Way,Two Way和OneTime的實現原理比較。
我的實際工作中發現,瞭解了SAP UI5這些資料繫結方式的實現,對我近期學習Angular的資料繫結也有一定的借鑑作用。
感謝閱讀。
系列目錄
(0) SAP UI5應用開發人員瞭解UI5框架程式碼的意義
(2) SAP UI5 控制元件渲染機制
(3) HTML原生事件 VS SAP UI5 Semantic事件
(6) SAP UI5控制元件資料繫結的實現原理(本文)
(7) SAP UI5控制元件資料繫結的三種模式:One Way,Two Way和OneTime實現原理比較
(8) SAP UI5控制元件ID的生成邏輯
(9) SAP UI5控制元件的多語言(國際化,Internationalization,i18n)支援的實現原理
(10) XML檢視裡的button控制元件
(11) button控制元件和它背後的DOM元素
更多Jerry的原創文章,盡在:"汪子熙":
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/24475491/viewspace-2754392/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 深入學習SAP UI5框架程式碼系列之四:SAP UI5控制元件的後設資料實現UI框架控制元件
- 深入學習SAP UI5框架程式碼系列之五:SAP UI5控制元件的例項資料修改和讀取邏輯UI框架控制元件
- 通過最簡單的button控制元件,深入學習SAP UI5框架程式碼系列之零控制元件UI框架
- SAP UI5 的資料繫結語法概述UI
- SAP UI5 初學者教程之十九 - SAP UI5 資料型別和複雜的資料繫結UI資料型別
- SAP UI5控制元件資料繫結的三種模式 - One Way, Two Way和OneTime實現原理比較UI控制元件模式
- SAP UI5 資料繫結中的工廠函式UI函式
- SAP UI5 初學者教程之二十 - SAP UI5 的表示式繫結用法講解UI
- 如何修改 SAP UI5 框架的原始碼實現,以及使用本地部署的 SAP UI5 SDK 試讀版UI框架原始碼
- SAP UI5框架自學教程UI框架
- 深入學習UI5框架程式碼系列之八:談談UI5 的檢視控制元件 ID,以及其和 Angular 檢視的異同UI框架控制元件Angular
- 什麼是 SAP UI5 的繫結路徑UI
- 透過一個具體的例子,深入瞭解 SAP UI5 控制元件資料雙向繫結的工作原理和問題排查方法UI控制元件
- SAP UI5 應用 SimpleForm 控制元件 ResponsiveGridLayout 佈局的工作原理深入剖析UIORM控制元件
- SAP UI5 初學者教程之十七 - 聚合繫結在 UI5 複合控制元件中的使用試讀版UI控制元件
- SAP UI5 初學者教程之十一 :SAP UI5 容器類控制元件 Page 和 PanelUI控制元件
- SAP UI5 sap.ui.layout.Grid 控制元件概述UI控制元件
- SAP UI5 應用裡 FlexBox 控制元件的設計原理UIFlex控制元件
- SAP UI5 資料型別(data type) 學習筆記UI資料型別筆記
- SAP UI5 框架的 manifest.jsonUI框架JSON
- SAP UI5 Negative cache的工作原理UI
- 關於SAP UI5資料繫結我的一些原創內容UI
- SAP UI5 初學者教程之六 - 瞭解 SAP UI5 的模組(Module)概念試讀版UI
- SAP UI5 DynamicPage 控制元件介紹UI控制元件
- SAP UI5 FlexibleColumnLayout 控制元件介紹UIFlex控制元件
- 如何實現SAP UI5 Web Component React控制元件的載入效果UIWebReact控制元件
- SAP UI5 的 TypeScript 實踐UITypeScript
- SAP UI5 資料繫結語法裡的特殊符號,以及絕對繫結和相對繫結概念詳解UI符號
- SAP UI5 Web Component的圖示實現UIWeb
- SAP UI5 SimpleForm 控制元件的 adjustLabelSpan 屬性UIORM控制元件
- SAP UI5 檢視裡的 OverflowToolbar 控制元件UI控制元件
- SAP UI5和CRM WebUI的View和Controller是如何繫結的UIWebViewController
- 深入介紹 UI5 框架裡 Smart Field 控制元件的工作原理UI框架控制元件
- SAP UI5 初學者教程的學習目錄UI
- 關於 SAP UI5 裝置型別檢測的實現原理UI型別
- SAP UI5 確保控制元件 id 全域性唯一的實現方法UI控制元件
- 關於 SAP UI5 Container 控制元件 aggregation 的深入分析試讀版UIAI控制元件
- SAP UI5 Theme Library 的解析邏輯和 SAP UI5 配置後設資料的預設值UI