2016-02-04 43 views
1

我有兩個模型定義在我的Component.js。一個是所有聯繫人的列表,另一個只是登錄的聯繫人。現在我想檢查我的控制器,如果登錄的聯繫人已經存在於所有聯繫人列表中。我從列表中重新比較登錄聯繫人的令牌中的registrationToken。但是當我通過列表循環時,由於異步通信,長度爲0。 只見attachRequestCompleted功能,但現在我有一個問題......當我的附加功能是填補我的視圖模型的OnInit的功能已經完成..SAPUI5/OpenUI5:模型attachRequestCompleted onInIn函數

onInit : function(){ 
    var gLocalContact = sap.ui.getCore().getModel("gLocalContact"); 
    var gRemoteContacts = sap.ui.getCore().getModel("gRemoteContacts"); 

    gRemoteContacts.attachRequestCompleted(function() { 
     ... if ... setProperty to gLocalContact.getProperty("/registrationToken")... 
     console.log("I should be the first log to get the data in view"); 
    }); 

    console.log("I should be the second log!"); 
    this.getView().setModel(gLocalContact, "localContact"); 
} 

第一個日誌中附上功能應該是第一個因爲我在那裏定義了一些數據到gLocalContact我需要在我看來。另一個問題是,我無法訪問我的gLocalContact變量....

回答

2

這有點難看,因爲SAPUI5不支持承諾。因此,在視圖內部,您不知道requestCompleted事件是否會被觸發,或者數據是否已經被加載。還有一些正在添加的解決方案,以我的腦海:

  1. 附上requestCompleted事件處理程序在你的組件之前調用loadData()。那麼你可以確保你會得到這個活動。 你將不得不建立你的視圖來處理一個空的gLocalContact模型。但是一旦模型被填充數據,綁定將更新視圖。

  2. 將您的onInit()的剩餘內容放入您的eventhander中。爲確保獲得該事件,請檢查模型中是否已有數據,如果是這樣,請手動調用您的事件處理程序以使其至少運行一次。

  3. 使用jQuerys Promise進行同步。這使您可以等待第二個模型太:

onInit : function(){ 
    var gLocalContact = sap.ui.getCore().getModel("gLocalContact"); 
    var gRemoteContacts = sap.ui.getCore().getModel("gRemoteContacts"); 

    console.log("Wait some seconds for the data..."); 
    var localContactPromise = this.getPromise(gLocalContact, "/origin"); 
    localContactPromise.done(function() { 
    //same code as before but this time you can be shure its called. 
    //... if ... setProperty to 
    //gLocalContact.getProperty("/registrationToken")... 
    console.log("I should be the first log to get the data in view"); 
    }); 

    var remoteContactsPromise = this.getPromise(gRemoteContacts,"/origin"); //Wait for the other model to 
    $.when(localContactPromise, remoteContactsPromise).done(function(){ 
    //When both models are loaded do this 
    console.log("I should be the second log!"); 
    this.getView().setModel(gLocalContact, "localContact"); 
    this.byId("label").setText("all loaded"); 
    }.bind(this)); 
}, 
getPromise:function(oModel, pathToTestForData){ 
    var deferred = $.Deferred(); 
    if (oModel.getProperty(pathToTestForData)) 
    deferred.resolve(); //Data already loaded 
    else 
    oModel.attachRequestCompleted(deferred.resolve); //Waiting for the event 

    return deferred.promise(); 
} 

完全example on JSBin

一個Promise是具有完成的事件對象。 A Deferred是具有Promiseresolve()方法的對象,該方法將引發該Promise上的完成事件。如果您首先在延遲上呼叫resolve(),然後註冊done的處理程序,則立即調用處理程序。所以即使你比異步加載請求慢,你也不會錯過這個事件。

但是:如果您的模型甚至在您的視圖初始化時甚至無法在組件/核心上設置,您會遇到嚴重問題,因爲沒有modelChanged事件。我建議創建一個空模型並將其分配給組件init-method中的組件,然後在該模型上使用loadData()

+0

感謝您的回答,我嘗試過,但我還沒有解決它。我發現,當我只記錄json模型時,我可以看到數據。當我使用* console.log(jsonModel.oData); *或* console.log(jsonModel.oData.length); *它的一個空對象或未定義。當我在我的attachRequestCompleted函數中使用它時,它工作的很好,但有jsonModel2.getProperty()爲空。 – WhoAmIReally

+0

也許第二個模型尚未完成加載時,第一個模型?你有沒有試過我的第三個解決方案有了承諾,您可以輕鬆等待多個異步請求。 – schnoedel

+0

我試過你的JSBin,但是我還沒有在我的項目中實現它...我會試着理解它是如何工作的 – WhoAmIReally