-
Notifications
You must be signed in to change notification settings - Fork 0
UI5 Basics of Routing
Single-page applications based on SAPUI5 can use a so-called “router” to dispatch hash-based URLs to one or more views of the app. Therefore, the router needs to know how to address and show the views. In SAPUI5, we can simply add a routing section to our existing sap.ui5
section in the descriptor file manifest.json
to configure the router.
.
├── ProjectFolder
│ └── webapp
│ ├── controller
│ │ └── App.controller.js
| | └── Home.controller.js
│ ├── css
│ ├── i18n
│ ├── view
│ │ └── App.view.xml
| | └── Home.view.xml
│ ├── Component.js
│ ├── index.html
│ └── manifest.json
├── package.json
├── readme.md
└── ui5.yaml
config
This section contains the global router configuration and default values that apply for all routes and targets. The property routerClass is special as it determines the router implementation. The default value is sap.ui.core.routing.Router
. Here, we set the routerClass to sap.m.routing
.Router, because we implement an app based on sap.m
. All other properties in config are given to the router instance. For example, we define where our views are located in the app. To load and display views automatically, we also specify the controlId of the control that is used to display the pages and the aggregation (controlAggregation) that will be filled when a new page is displayed. We will create only XMLviews in this tutorial, so we can set the viewType property to XML. All our views will be available in the view folder of the namespace "someNamespace.projectName", so we can set the viewPath to someNamespace.projectName.view
. The transition allows us to set a default value for how the transition should happen; you can choose between slide (default), flip, fade, and show. All parameters of the config section can be overruled in the individual route and target definitions if needed.
-
Note:
The possible values for routerClass are
sap.ui.core.routing.Router
,sap.m.routing.Router
, or any other subclasses ofsap.ui.core.routing.Router
. Compared tosap.ui.core.routing.Router
thesap.m.routing.Router
is optimized for mobile apps and adds the properties viewLevel, transition and transitionParameters which can be specified for each route or target created by thesap.m.routing.Router
. The transitionParameters can also be used for custom transitions. Please check the API Reference for more information.
routes
Each route defines a name, a pattern, and one or more targets to navigate to when the route has been hit. The pattern is basically the hash part of the URL that matches the route. The sequence of the routes is important because only the first matched route is used by the router. In our case, we have an empty pattern to match the empty hash. The name property allows you to choose a unique route name that helps you to navigate a specific route or to determine the matched route in one of the matched handlers (we'll explain that in a later step). The target property references one or more targets from the section below that will be displayed when the route has been matched.
- TLDR: You use routes to notify your application that the hash has changed to a certain value. For each route, you define the pattern that can be used in the app implementation.
targets
A target defines the view that is displayed. It is associated with one or more routes or it can be displayed manually from within the app. Whenever a target is displayed, the corresponding view is created (or loaded from cache) and added to the aggregation configured with the controlAggregation option of the control. This option is configured using controlId. Each target has a unique key viewId
(home), this represents the actual id
in the rendered DOM element (i.e. home
could result in the following Id container-com.<some>.<namespace>---home--page
. The viewName
defines which view shall be loaded. In our little example, the absolute view path to be loaded for our home target is determined by the default "viewPath": "someNamespace.projectName.view" and "viewName": "Home". This leads to "someNamespace.projectName.view.Home". The viewLevel is especially relevant for flip and slide transitions. It helps the router to determine the direction of the transition from one page to another. (This will also be explained later.) A target can be assigned to a route, but it's not necessary. Targets can be displayed directly in the app without hitting a route.
- TLDR: With targets, you define where a view is loaded and where the view is shown on the UI. By referring to one or multiple targets in a route's definition, you can load and show the views once the route's pattern matches the current hash.
"sap.ui5": {
"rootView": {
"viewName": "someNamespace.projectName.view.App",
"type": "XML",
"async": true,
"id": "app"
},
"routing": {
"config": {
"routerClass": "sap.m.routing.Router",
"viewType": "XML",
"viewPath": "someNamespace.projectName.view",
"controlId": "app",
"controlAggregation": "pages",
"transition": "slide",
"async": true
},
"routes": [{
"name": "appHome",
"pattern": "",
"target": ["home"]
}],
"targets": {
"home": {
"viewType": "XML",
"viewId": "home",
"viewLevel": 1,
"viewName": "Home"
}
}
}
}
Basically what we do here is, we define our main view called "App" to be loaded initially when starting up the application, as it is declared as rootView
within our manifest.json. We then use the routing configuration with an initial (empty) route to display some content. We do this by using the property controlId
and controlAggregation
. The Router uses the initial route which points to our second view called "Home" and adds it into to the "App" view or rather into the App control as aggregation of pages
. Therefore our "Home" view only needs to declare the aggregation Page
which encapsulates our content.
App-View
<mvc:View
controllerName="someNamespace.projectName.controller.App"
xmlns="sap.m"
xmlns:mvc="sap.ui.core.mvc"
displayBlock="true">
<Shell>
<App id="app"/>
<!--The Home-View will be added into the App-Control via the Router;
The Routing configuration tells the framework which controlId and which
controlAggregation it has to 'target' for the placement of the View;
Home-View implements the <page> and all it's content-->
</Shell>
</mvc:View>
Home-View
<mvc:View
controllerName="someNamespace.projectName.controller.Home"
xmlns="sap.m"
xmlns:mvc="sap.ui.core.mvc">
<Page title="{i18n>homePageTitle}" class="sapUiResponsiveContentPadding">
<content>
<Button text="{i18n>iWantToNavigate}" class="sapUiTinyMarginEnd"/>
</content>
</Page>
</mvc:View>
Whenever a hash is added to a URL, the router checks whether there is a route with a matching pattern. The first matching route is taken and the corresponding target view is called (order of definition matters). The data provided with the hash is passed on to the target.
-
Hard-coded pattern:
The pattern matches the hash exactly. For example, when a pattern is defined as
product/settings
, this pattern matches only if the hash isproduct/settings
and no data is passed on to the events of the route. -
Route with mandatory parameter:
You can define mandatory parameters for the pattern by placing the parameter in curly brackets
{parameter ID}
.For example, if you define the pattern
product/{id}
, the hashesproduct/5
andproduct/3
(where3
and5
are product IDs) match the pattern. The matched event handler gets5
or3
passed on with the key id in its arguments. But hashproduct/
does not match the pattern because the mandatory parameter is missing. -
Route with optional parameter:
You can define optional parameters for the pattern by placing the parameter between colons
:parameter ID:
.For example, if you define a pattern
product/{id}/detail/:detailId:
, thedetailId
parameter is optional, whereasid
is mandatory. Both hashesproduct/5/detail
andproduct/3/detail/2
match the pattern. -
Route with query parameter:
The query parameter allows you to pass on queries with any parameter. A query parameter starts with
?
, and you can either define it as mandatoryproduct{?query}
or optionalproduct:?query:
.The matched value will be converted into an object saved with the parameter name as the key when passed to the event handler.
Route: {parameterName1}/:parameterName2:/{?queryParameterName}
{ "parameterName1": "parameterValue1", "parameterName2": "parameterValue2", "?queryParameterName": { "queryParameterName1": "queryParameterValue1" } }
Example from the
.navTo
method of thesap.ui.core.routing.Router
documentation. -
"rest as string" parameter:
A parameter that ends with an asterisk
*
is called a "rest as string" parameter. Such a parameter matches as much as possible. It can be combined with the syntax of mandatory or optional parameters.For example, a
pattern product/{id}/:detail*:
defines a mandatory parameter with the nameid
and an optional "rest as string" parameter with the namedetail
. It matchesproduct/5/3
andproduct/5/detail/3/foo
. The event handler gets3
ordetail/3/foo
passed on with the key detail in its arguments. -
Note: SAPUI5 uses Crossroads.js for parsing the hash and the Hasher framework for manipulating the hash.
- Configure the router in the manifest.json descriptor file
- Initialize the router exactly once
- Initialize the router in the component
The repository is here.