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:
_onUrlMatched
callbacks are correctly fired and the current URL parameters are successully parsed._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?
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>