深入學習SAP UI5框架程式碼系列之六:SAP UI5控制元件資料繫結的實現原理

i042416發表於2021-01-29

這是Jerry 2021年的第 7 篇文章,也是汪子熙公眾號總共第 278 篇原創文章。

系列目錄

(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實現原理比較

(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屬性。


深入學習SAP UI5框架程式碼系列之六:SAP UI5控制元件資料繫結的實現原理


這樣一來,執行時看到按鈕的標籤就成了field_for_text的值"Jerry",而不是第18行給text屬性賦予的硬編碼值"Button":


深入學習SAP UI5框架程式碼系列之六:SAP UI5控制元件資料繫結的實現原理


本文的目的就是,闡述清楚第一張圖高亮的五行程式碼,背後發生了什麼事情。

var oModel = new sap.ui.model.json.JSONModel();


深入學習SAP UI5框架程式碼系列之六:SAP UI5控制元件資料繫結的實現原理


當這行程式碼執行之後,JSONModel以及包含對應的模型繫結實現邏輯的JavaScript原始檔會自動被載入,這體現了SAP UI5 Module的懶載入特性,在本系列這篇文章裡介紹過: 深入學習SAP UI5框架程式碼系列之一:UI5 Module的懶載入機制


深入學習SAP UI5框架程式碼系列之六:SAP UI5控制元件資料繫結的實現原理


本系列之前的文章,我們曾經多次提及SAP UI5控制元件的原型繼承鏈:

Button -> Control -> Element -> ManagedObject

-> EventProvider -> BaseObject

本文我們會學習到另一條原型繼承鏈:

JSONModel -> ClientModel -> Model -> MessageProcessor -> EventProvider -> BaseObject


深入學習SAP UI5框架程式碼系列之六:SAP UI5控制元件資料繫結的實現原理


從上圖第61行的建構函式的輸入引數oData,不難發現,在UI5應用裡建立JSONModel例項時,可以將模型儲存的資料一併指定。

這樣,我們之前腳手架應用裡的程式碼,可以精簡成下圖右邊所示:


深入學習SAP UI5框架程式碼系列之六:SAP UI5控制元件資料繫結的實現原理


單步除錯JSONModel的建構函式,會發現它依次會呼叫原型繼承鏈上游節點的ClientModel,Model和MessageProcessor的建構函式。

下圖是Model建構函式的實現,資訊量很大:

(1) 第69行,說明SAP UI5模型繫結的預設方式是雙向繫結;

(2) 第83行,說明SAP UI5模型繫結支援單向,雙向和單次繫結。本系列下一篇文章 SAP UI5控制元件資料繫結的三種模式:One Way,Two Way和OneTime實現原理比較 會介紹這三種方式的區別。


深入學習SAP UI5框架程式碼系列之六:SAP UI5控制元件資料繫結的實現原理


oModel.setData(myData);

將一個JSON物件通過setData傳入JSONModel例項。


深入學習SAP UI5框架程式碼系列之六:SAP UI5控制元件資料繫結的實現原理


setData方法有一個可選引數bMerge,如果顯式指定為true,則會呼叫下圖88行的jQuery.extend, 將本地傳入的JSON物件同JSONModel原有的資料進行合併(merge). 因為我們本例呼叫setData並未指定該引數,所以不進行合併,直接執行95行的checkUpdate:


深入學習SAP UI5框架程式碼系列之六:SAP UI5控制元件資料繫結的實現原理


因為此時UI5 button控制元件例項尚未同JSONModel例項建立繫結關係,所以模型的aBindings陣列為空,因此checkUpdate實際並未執行任何和控制元件繫結相關的操作,直接返回。


深入學習SAP UI5框架程式碼系列之六:SAP UI5控制元件資料繫結的實現原理


oButton1.setModel(oModel);

這行語句的作用,就是將控制元件例項和傳入方法的JSONModel例項建立繫結關係。

  • 4597~4604:該IF分支處理UI5控制元件之前已經繫結到某個模型例項的情況,此時使用delete操作,刪除原有的模型引用,然後更新繫結資訊。而本例是button控制元件第一次呼叫setModel,故不會進入此IF分支。


深入學習SAP UI5框架程式碼系列之六:SAP UI5控制元件資料繫結的實現原理


  • 4607:UI5控制元件維護了一個類似字典的鍵值對資料結構,key為模型名稱,value為模型例項。從此處的SAP UI5原始碼實現不難得出結論,UI5控制元件支援同時繫結到多個模型例項上,只要該控制元件在呼叫setModel方法時,給傳入的模型例項通過方法第二個引數sName,賦予不同的模型名稱即可。


深入學習SAP UI5框架程式碼系列之六:SAP UI5控制元件資料繫結的實現原理


至此,JSONModel例項的field_for_text欄位值,還不會自動流向button控制元件的text屬性,直到下面這行程式碼的執行。

oButton1.bindProperty(“text”, “/field_for_text”);

該方法首先構造了一個包含JSONModel繫結欄位的物件oBindingInfo:


深入學習SAP UI5框架程式碼系列之六:SAP UI5控制元件資料繫結的實現原理


將該oBindingInfo維護到控制元件的中央繫結資訊儲存資料結構mBindingInfos裡,該資料結構同樣是一個鍵值對,key為控制元件屬性,本例為text,值為oBindingInfo物件,物件裡包含了text屬性繫結到JSONModel例項的欄位名稱:field_for_text.


深入學習SAP UI5框架程式碼系列之六:SAP UI5控制元件資料繫結的實現原理


單步除錯進入上圖3347行的_bindProperty方法:

3417行,呼叫JSONModel的bindProperty方法,生成oBinding物件:


深入學習SAP UI5框架程式碼系列之六:SAP UI5控制元件資料繫結的實現原理


這裡再次出現了關於SAP UI5資料繫結的三種模式處理的原始碼,本系列後續文章會專門介紹。

3433行將生成的oBinding物件例項,新增到aBindings陣列裡。


深入學習SAP UI5框架程式碼系列之六:SAP UI5控制元件資料繫結的實現原理


那麼oBinding例項是如何生成的?需要單步除錯上圖3417行的oModel.bindProperty程式碼。


深入學習SAP UI5框架程式碼系列之六:SAP UI5控制元件資料繫結的實現原理


JSONModel.bindProperty的實現,就是一個單純的new呼叫。不過更重要的是,此處我們瞭解到了另一條原型繼承鏈:

JSONPropertyBinding -> ClientPropertyBinding -> PropertyBinding -> Binding -> EventProvider -> BaseObject


深入學習SAP UI5框架程式碼系列之六:SAP UI5控制元件資料繫結的實現原理


我們注意到,在oBinding例項裡,有個欄位叫做oValue, 其值正好是JSONModel例項維護的JSON物件欄位field_for_text的值Jerry. 實際上,最後button控制元件的text屬性,顯示的值正是oBinding例項oValue欄位的值。


深入學習SAP UI5框架程式碼系列之六:SAP UI5控制元件資料繫結的實現原理


所以需要搞清楚this.oValue的賦值邏輯,就得單步執行上圖第35行的this._getValue方法。

this._getValue()

該函式負責將field_for_text欄位的值,從this.oModel.oData.field_for_text欄位中提取出來,如下圖所示:


深入學習SAP UI5框架程式碼系列之六:SAP UI5控制元件資料繫結的實現原理


一旦this._getValue執行完之後,控制元件text屬性同JSONModel例項的field_for_text欄位就成功建立起繫結關係,之後我們就能直接從控制元件例項變數oButton1出發,去找到其text屬性應該顯示的值:


深入學習SAP UI5框架程式碼系列之六:SAP UI5控制元件資料繫結的實現原理


希望通過本文的介紹,能讓大家對SAP UI5控制元件資料繫結的實現原理有一個最基本的瞭解。

如果遇到控制元件繫結不能按照自己的期望工作的時候,不妨試試按照本文提到的這些關鍵點去除錯。

本系列下一篇文章,會介紹SAP UI5控制元件資料繫結的三種模式:One Way,Two Way和OneTime的實現原理比較。

我的實際工作中發現,瞭解了SAP UI5這些資料繫結方式的實現,對我近期學習Angular的資料繫結也有一定的借鑑作用。

感謝閱讀。


深入學習SAP UI5框架程式碼系列之六: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實現原理比較

(8) SAP UI5控制元件ID的生成邏輯

(9) SAP UI5控制元件的多語言(國際化,Internationalization,i18n)支援的實現原理

(10) XML檢視裡的button控制元件

(11) button控制元件和它背後的DOM元素

更多Jerry的原創文章,盡在:"汪子熙":

深入學習SAP UI5框架程式碼系列之六:SAP UI5控制元件資料繫結的實現原理


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/24475491/viewspace-2754392/,如需轉載,請註明出處,否則將追究法律責任。

相關文章