Search code examples
odatasapui5sap-fiori

Fiori Master Detail App routing with mutliple parameters


I'm currently working on my first SAP Fiori App. In SAP WebIDE I created a project from template using Master Detail and connected it to my oData Service.

If I run the unmodified App, everything works except that no data gets loaded on Detail View because the oData Service expects 2 parameters to get a unique record.

Now the problem is, if I modify the app to use 2 parameters and navigate to the Detail View, the Detail View loads, but doesn't even hit the oData Service. (No $batch Request in Chrome Dev Tools)

Modifications in manifest.json

    {
        "pattern": "JOBSSet/{Jobname}/{Jobcount}",
        "name": "object",
        "target": [
        "master",
        "object"
        ]
    }

Modification of Master Controller:

    _showDetail : function (oItem) {
            var bReplace = !Device.system.phone;
            // set the layout property of FCL control to show two columns
            this.getModel("appView").setProperty("/layout", "TwoColumnsMidExpanded");
            this.getRouter().navTo("object", {
                Jobname : encodeURIComponent(oItem.getBindingContext().getProperty("Jobname")),
                Jobcount : oItem.getBindingContext().getProperty("Jobcount")
            }, bReplace);
        }

Modification of Detail Controller:

_onObjectMatched : function (oEvent) {

            var sJobname =  decodeURIComponent(oEvent.getParameter("arguments").Jobname);
            var sJobcount =  oEvent.getParameter("arguments").Jobcount;

            this.getModel("appView").setProperty("/layout", "TwoColumnsMidExpanded");
            this.getModel().metadataLoaded().then( function() {
                var sObjectPath = this.getModel().createKey("JOBSSet", {
                    Jobname :  sJobname,
                    Jobcount : sJobcount
                });
                this._bindView("/" + sObjectPath);

            }.bind(this));
        }

Solution

  • This behavior only happens when you run the app starting from its first page.

    If you for example test the app in a smartphone (or using Chrome Dev Tools to simulate that) you'll see that when the app is opened directly to the detail page, there will be a network call to get the item detail. It will be a $batch call as well but inside it you will find a 'GET /JOBSSet(Jobname='x',Jobcount='y').

    Basically what happens is the following: By default UI5 caches your data in Context objects (assuming you are using the v2.ODataModel class). When you run the app and see a list of "Jobs", the library already created a Context object for each record returned from your oData service.

    If later on in the app you create a Context object (directly or indirectly, like the bindElement method) UI5 will check the given path - /JOBSSet(Jobname='x',Jobcount='y'). If there is already a Context linked with that path, then the Context should already exist in the main memory. So, no extra call should be needed.