2017-07-26 20 views
2

我試圖從OData源中準備數據以在我的fiori應用程序的條形圖中顯示它。爲此,我在manifest.json中設置OData模型。用列表測試,只需使用在控制器的onInit中讀取OData上下文

items="{path : 'modelname>/dataset'} 

正常工作並顯示內容。爲了準備圖(VizFrame)的數據,我在視圖控制器(mvc:XMLView)中使用了onInit()函數。數據準備與question中討論的相似。

起初我獲得ODataModel:

var oODataModel = this.getOwnerComponent().getModel("modelname"); 

接下來我做的綁定:

var oBindings = oODataModel.bindList("/dataset"); 

不幸的是,oBindings().getContexts()陣列始終是空的,也oBindings.getLength()爲零。因此,VizFrame只顯示「無數據」。

這可能是數據模型在onInit()函數期間未被完全加載,還是我誤解了訪問數據的方式?

預先感謝

更新 我臨時使用自動創建的綁定從顯示數據作爲列表視圖解決了這個問題。我從綁定getView().byId("myList").getBindings("items") grep的「dataReceived」事件,並在那裏做我的計算。該圖的模型(因爲它在不同的視圖中使用)在Component.js中創建,並在Core sap.ui.getCore().setModel("graphModel")中註冊。 我認爲這個解決方案很髒,因爲圖表數據取決於來自不同視圖的列表數據,這會導致問題,例如,當您使用增長列表時(因爲綁定中的數據得到更新並且從odata模型中選擇了不同的範圍)。 任何建議,我如何獲得odata模型條目而不依賴於不同的列表?

回答

0

也許是在onInit() 函數中數據模型沒有完全加載,或者我誤解了訪問數據的方式?

您可以測試,如果你的模型,完全由控制檯登錄加載它,你做的列表綁定

console.log(oODataModel); 
var oBindings = oODataModel.bindList("/dataset"); 

之前,如果模型中不包含任何數據,那麼這就是問題所在。

+0

控制檯顯示模型。例如。在mContexts下面是來自oData的前20個條目的列表,並且aBindings包含具有81個對象(其每個都具有屬性sPath =「/ dataset」)的數組。 –

1

您必須等待模型元數據加載完畢。試試這個:

onInit: function() { 
    var oBindings; 
    var oODataModel = this.getComponent().getModel("modelname"); 
    oODataModel.metadataLoaded().then(function() { 
     oBindings = oODataModel.bindList("/dataset"); 
    }.bind(this)); 
}, 
+0

謝謝,我認爲這指向了正確的方向。但是爲了理解:當執行「then」後面的函數時?在我的例子中,metadataLoaded()函數返回'[[PromiseStatus]]:「resolved」',並且oBindings被設置? metadataLoaded()函數與attachMetadataLoaded()類似嗎? –

+0

我無法確切地告訴你。我猜是這樣。嘗試attachMetadataLoaded :-) – alexP

+0

我現在有'oODataModel.attachMetadataLoaded(處理程序);'它被調用。在處理程序的函數內部,oODataModel具有屬性oMetadata-> bLoaded:true,還有一個oData對象,其中包含我的odata的前20個條目。但是,getContexts()仍然是空的。 –

2

下圖概述了你的UI5應用程序的生命週期。

enter image description here

重要的是其突出的紅色圓圈中的步驟。基本上,在您的onInit中,您無法通過this.getView().getModel()完全訪問您的型號。

這可能是爲什麼你嘗試使用this.getOwnerComponent().getModel()。這使您可以訪問模型,但它不受視圖限制,因此您沒有任何上下文。

類似地metadataLoaded()返回一個滿滿的Promise有點太早了:恰好在元數據加載之後,這可能是在任何視圖綁定完成之前。

我最常做的是

  • 使用onBeforeRendering

這是生命週期掛鉤,被onInit後立即調用。該視圖及其模型存在,但它們尚未顯示給用戶。與你的模型做東西的可能性很大。

  • 使用onRouteMatched

這是不是一個真正的生命週期掛鉤,但它可以綁定到你的應用程序的路由器對象的事件處理程序。由於您在onInit中定義了事件處理程序,因此稍後會調用它(但不會太晚),然後您可以執行所需的任務。這顯然只在你設置路由時才起作用。

+0

這篇文章的答案超過了原來的問題。非常有價值的圖表,謝謝。我將評估移到了onBeforeRendering函數中。 但現在我想,我的問題是綁定本身。在視圖本身中我沒有任何約束力。例如。在列表中我有一些類似'items =「{path:'...'}'的東西,它會自動創建綁定,所以也許,問題實際上是:如何手動添加這種綁定到視圖? –

+0

請告訴如果我理解了這個圖表, *在控制器的init函數中,我將listBinding添加到數據模型中(這看起來很有效,因爲綁定可以在顯示模型的調試輸出中找到) * In 「綁定的評估」和「數據檢索」我的綁定應該填充數據,或者??當視圖被更新時(函數onBeforeRendering被調用?),我應該可以訪問來自綁定的數據,例如獲取上下文? 由列表自動創建的綁定,數據可用,但不是手動創建的。爲什麼? –

+0

我不完全確定你爲什麼需要上下文......你能詳細說明一下嗎? – Marc

0

我最基本的誤解是強制使用綁定。這似乎只適用於組織數據處理的UI元素。我切換到

oODataModel.read("/dataset", {success: function(oEvent) { 
    // do all my calculations on the oEvent.results array 
    // write result into graphModel 
    } 
}); 

這整個計算是在連接到向GraphModel,這是在視圖/控制器的onBeforeRendering部分設定爲模型的VizFrame的requestSent事件的函數。