cancel
Showing results for 
Search instead for 
Did you mean: 

How to differentiate multiple requests attached to one oData model

Former Member
0 Kudos

Hello,

Looking for best practice / ideas on how to structure our app to handle multiple attachRequestSent / attachRequestCompleted events to the same oData Model.  On one particular page I have a tab control with each tab having a table which is bound to a separate HANA calculated view within the same .xsodata file.

The issue is that the attachRequestCompleted cannot differentiate (as far as I can tell) which data is returned for the appropriate tab.  So, if I'm on say, Tab E, and the data for Tab A returns, the attachRequestCompleted event fires for all tabs/tables, and the busyIndicator for the table on Tab E (and every other tab) stops/hides, even though the data for Tab E has not returned yet.

Moreover, if you navigate to another page within the application, subsequent data pulls on other pages using the same model now continue to trigger the attachRequestCompleted for each of the tabs on the original screen.

Is there a recommended way to setup specific listeners for separate events like these, or should we have a distinct data model for each tab, or...?


onMaterialChange: function(mtrlCode) {

       var materialFilter = [ui5.createTableFilter("MTRL", 'equals', mtrlCode, null)];

       oLEMTabsController.refreshInventoryGrid(materialFilter);

       oLEMTabsController.refreshProductionGrid(mtrlCode);

       oLEMTabsController.refreshBatchLvlInvnGrid(mtrlCode, oPlant);

       oLEMTabsController.refreshDistributionNetworkGrid(materialFilter);

       oLEMTabsController.refreshShipmentsGrid(mtrlCode);

       oLEMTabsController.refreshExceptionsGrid(mtrlCode);

       oLEMTabsController.refreshPMTsGrid(mtrlCode);

       oLEMTabsController.refreshSalesOrdersGrid(mtrlCode, oPlant);

       oLEMTabsController.refreshPMTIntransitGrid(mtrlCode);

},


refreshInventoryGrid: function (filter) {

       var oTableInventory = utilities.getControlFromUI("tblInventory");

       oTableInventory.setThreshold(10);

       oTableInventory.setBusyIndicatorDelay(0);

       oTableInventory.bindRows({

            path: "/TAB_INVN",

            filters: filter

       }).rerender();

       oDataModel.attachRequestSent(function (oEvent) {

            oTableInventory.setBusy(true);

       });

       oDataModel.attachRequestCompleted(function (oEvent) {

            oTableInventory.setBusy(false);

       });

       oDataModel.attachRequestFailed(function (oEvent) {

            oTableInventory.setBusy(false);

       });

},


refreshProductionGrid: function (code) {

       if (code){

            oLEMTabsController.refreshGrid("tblProduction", "/TAB_PRODNParameters(IN_MTRL='"+code+"')/Results");

       }

},

[and so on...]


refreshGrid: function(tableId, oPath){

      var oTable = utilities.getControlFromUI(tableId);

      oTable.setThreshold(100);

      oTable.setBusyIndicatorDelay(0);

      oTable.bindRows({

           path: oPath

      }).rerender();

      oDataModel.attachRequestSent(function (oEvent) {

            oTable.setBusy(true);

      });

      oDataModel.attachRequestCompleted(function (oEvent) {

            oTable.setBusy(false);

      });

      oDataModel.attachRequestFailed(function (oEvent) {

            oTable.setBusy(false);

      });

},

Accepted Solutions (1)

Accepted Solutions (1)

former_member195440
Participant
0 Kudos

One way could be to keep track of the URLs used for the request. There is a lot of information coming back in the "oEvent" parameter you are not using in the callbacks:


{string}                                    oControlEvent.getParameters.url           The url which was sent to the backend

Reference - OpenUI5 SDK - Demo Kit

It does seem wrong though. Have you explored various binding techniques for your table controls? Usually changing the binding automatically reloads and does the necessary wait timers etc.

Oli

Former Member
0 Kudos

Thanks Oli.  Unfortunately the url parameter returned just points back to the shared .xsodata file.

I'm ok with changing the way the table is bound, but it seems like we'd have the same issue since the attachRequestCompleted event is attached to the shared data model itself.

SandipAgarwalla
Active Contributor
0 Kudos

Instead of listening to the events on the odata model, you can listen to the events on the bindings of the perticular UI element. e.g. Table, list.

when ever the list data changes, it fires an event

oListBindings = this.getList().getBinding('items');

oListBindings.attachDataReceived(function(oEvent){

}

hope this helps.

Former Member
0 Kudos

Sandip, I like your answer very much - it is working beautifully for the first data pull.  There is an issue though - on subsequent data pulls which happen to return the same data, the oTable.getBinding().attachDataReceived() never fires, so the busy signal spins indefinitely.  I presume this is because the data in the table did not change, but I have tried clearing out the table's rows, oData, etc on subsequent calls, and it does not seem to help. 

Any thoughts on how to make it fire this event more than once per table?

former_member182372
Active Contributor
0 Kudos

>>on subsequent data pulls which happen to return the same data,


What are those? How to you force them? Code?

SandipAgarwalla
Active Contributor
0 Kudos
on subsequent data pulls which happen to return the same data

what kind of pull? is it filters?

on a pull, does it fire a new oData call? check the network console, if it fires another http request. If its does not fire a http request, then the event would not be fired.

Add a code snippet here what you have done..

Former Member
0 Kudos

Actually, I think it wasn't doing quite what I described in my reply above.  I was still attaching the attachRequestSent event to the model, but listening for the the dataReceived on the table binding, like this:


oDataModel.attachRequestSent(function (oEvent) {

       oTableInventory.setBusy(true);

  });

  oTableInventory.getBinding().attachDataReceived(function(oEvent){

       oTableInventory.setBusy(false);

  });

  oDataModel.attachRequestFailed(function (oEvent) {

       oTableInventory.setBusy(false);

  });

So when I clicked on another tab which kicked off a separate data retrieval, it was setting the inventory tab to busy based on the attachRequestSent event for the shared model, and never hitting the tablel binding's attachDataReceived again.  Really what was needed, and seems to be working, is this:


  oTableInventory.getBinding().attachDataRequested(function(oEvent){

       oTableInventory.setBusy(true);

  });

  oTableInventory.getBinding().attachDataReceived(function(oEvent){

       oTableInventory.setBusy(false);

  });

  oDataModel.attachRequestFailed(function (oEvent) {

       oTableInventory.setBusy(false);

  });

Thanks everyone for your help.

Answers (0)