Search code examples
odatasapui5

How to bind an entity object on a Detail page


I am developing a master detail Fiori app using SAP UI5. As the details contains more than 40 columns, I made separate OData services for master & detail.

In Master page, data are coming correctly. Now my task is that on any table line, when user clicks on Detail, next page will be open with details base on two key values of master table.

I'm getting two keys in variables in detail page as follows and it is working fine:

var spayid = jQuery.sap.getUriParameters().get("payid");
var spaydt = jQuery.sap.getUriParameters().get("paydt");

Next, I have created two filters as follows which is also working fine.

var filter1 = new Filter({
  path: "Laufi",
  operator: FilterOperator.EQ,
  value1: spayid
});
var filter2 = new Filter({
  path: "Laufd",
  operator: FilterOperator.EQ,
  value1: spaydt
});

Now I am calling OData service which is also working fine:

var oODataModel = new ODataModel("proxy/http/FIORI-DEV.abc.com:8000/sap/opu/odata/sap/ZASA_FI_pay_D_SRV?sap-client=100", {
  json: true,
  useBatch: false
});
this.getView().setModel(oODataModel);

I don't know now how to filter data. What should be included in above so that it will filter data according to my filters filer1 and filter2? I have tried following but it is not working.

  filters : [ filter1, filter2 ],
  json: true,
  useBatch: false

I am very good in ABAP but not an expert in SAPUI5. I am in learning phase.

First of all, I was thinking to pass parameters on OData service so that only the required data are fetched. Means my OData call should be like this:

new ODataModel("proxy/http/FIORI-DEV.abc.com:8000/sap/opu/odata/sap/ZASA_FI_PAYMENT_D_SRV/PdetailSet(Laufi= spayid, Laufd = spaydt)?sap-client=100");

But this seems not like possible.

Second option is that I will fetch whole details in OData service and then during binding to table I will apply filter.


Solution

  • The purpose of the sap.ui.model.Filter class is usually to apply filters to lists on the UI. For example, if you have a list of items and you want to limit that list to a subset of items which fulfills certain criteria.

    But what you have here appears to be a classic master-detail scenario where you have a list of items and then when the user selects one show more information about that one item.

    The usual solution for such a scenario is to assign the full model to the detail-view and then use an element binding (also known as "context binding") on the view to tell it which item to display.

    When the source of the item is a click on an element which already had an element binding, then you can actually retrieve the correct binding path from the click event and just apply it to your detail-view.

    From one of the official demos:

    onItemSelected: function(oEvent) {
        var oSelectedItem = oEvent.getSource();
        var oContext = oSelectedItem.getBindingContext("products");
        var sPath = oContext.getPath();
        var oProductDetailPanel = this.byId("productDetailsPanel");
        oProductDetailPanel.bindElement({ path: sPath, model: "products" });
    }
    

    When you don't have any convenient way to get an element path from, then you have to construct one yourself:

    var detailPanel = this.getView().byId("idOfDetailPanel");
    detailPanel.bindElement("PdetailSet(Laufi = " + spayid +", Laufd = " + spaydt + ")");
    

    The latter code snippet does of course assume that the oData-service actually supports access with a key consisting of laufi and laufd. This is decided by:

    • The definition of the key fields of the entity type in the SAP Gateway Service Builder (transaction SEGW)
    • The ABAP implementation of the method get_entity of the data provider class of that oData-service.