Search code examples
javascriptsapui5

Router doesn't trigger onMatched callback when refreshing page in browser


I have an application with a RootComponent that contains two nested Components. One of these two Components, called UserComponent, displays a FlexibleColumnLayout and has a route with two URL parameters defined:

{
    "pattern": "detail/{objectId}/detailDetail/{treeObjectId}/{layout}",
    "name": "detailDetail",
    "target": [
        "list",
        "detail",
        "detailDetail"
    ],
    "greedy": true
}

Then, I try to access the respective URL parameters in the Controller like this:

onInit: function() {
    console.log("onInit() DetailController");
    // ...
    this.oRouter = this.getOwnerComponent().getRouter();
    this.oRouter.getRoute("list").attachMatched(this._onUrlMatched, this);
    this.oRouter.getRoute("detail").attachMatched(this._onUrlMatched, this);
    this.oRouter.getRoute("detailDetail").attachMatched(this._onUrlMatched, this);
},

_onUrlMatched: function(oEvent) {
    console.log("onUrlMatched()");
    // Fetch URL parameters...
    // Do something with the URL parameters...
},

The behaviour I observe is as follows:

  • When I expand the FlexibleColumnLayout by navigating through the Routes step by step (list, detail, detailDetail), the _onUrlMatched callbacks are correctly fired and the current URL parameters are successully parsed.
  • But when I reload the page, the _onUrlMatched callbacks are not called, even though the onInit() functions of all related Controllers are executed. The same happens when I paste the full URL in a new browser tab.

I already found an official sample project with nested Components where the behavior is similar to what I desire. However, the example doesn't use a FlexibleColumnLayout and I see no difference in the manifest.xml or Controller files to my implementation.

Why are the callbacks not fired when I reload the page?


Solution

  • After a lot of digging, I found the solution to the problem. It turned out that the router configuration in the manifest.xml was wrong. I had to change the configuration from

    "routing": {
        "config": {
            "routerClass": "sap.f.routing.Router",
            "viewType": "XML",
            "viewPath": "com.demo.admin.view",
            "controlId": "flexibleColumnLayout",
            "async": true,
            "transition": "slide"
        },
        //...
    }
    

    into

    "routing": {
        "config": {
            "routerClass": "sap.f.routing.Router",
            "type": "View",
            "viewType": "XML",
            "path": "com.demo.admin.view",
            "controlId": "flexibleColumnLayout",
            "async": true,
            "transition": "slide"
        },
        //...
    }
    

    I found out by comparing my current project to this sample project.


    For completeness, this is my index.html file for which this solution is working:

    <!DOCTYPE html>
    <html style="height: 100%">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Demo Admin</title>
    
        <script id="sap-ui-bootstrap"
            src="https://sapui5.hana.ondemand.com/resources/sap-ui-core.js"
            data-sap-ui-theme="sap_horizon"
            data-sap-ui-resourceroots='{
                "com.demo.admin": "./"
            }'
            data-sap-ui-xx-bindingSyntax="complex"
            data-sap-ui-oninit="module:sap/ui/core/ComponentSupport"
            data-sap-ui-compatVersion="edge"
            data-sap-ui-async="true"
            data-sap-ui-frameOptions="trusted">
        </script>
    </head>
    
    <body class="sapUiBody sapUiSizeCompact">
        <div data-sap-ui-component
            data-name="com.demo.admin"
            data-height="100%"
            data-id="container"
            data-settings='{"id" : "rootComponent"}'
            style="height: 100%">
        </div>
    </body>
    </html> 
    

    And this is my App.view.xml file:

    <mvc:View
        xmlns:mvc="sap.ui.core.mvc"
        xmlns="sap.f"
        xmlns:m="sap.m"
        controllerName="com.demo.admin.controller.App"
        displayBlock="true"
        height="100%">
    
        <FlexibleColumnLayout
            id="flexibleColumnLayout"
            backgroundDesign="Solid"
            stateChange=".onStateChanged"
            layout="{/layout}" />
    
    </mvc:View>