We can now navigate between the overview and the detail page, but the actual item that we selected in the overview is not displayed on the detail page yet. A typical use case for our app is to show additional information for the selected item on the detail page.
To make this work, we have to pass over the information which item has been selected to the detail page and show the details for the item there.
The selected invoice details are now shown in the details page
You can view all files at OpenUI5 TypeScript Walkthrough - Step 31: Routing with Parameters and download the solution as a zip file.
We want to hand over the information for the selected item when navigating to the detail view. To achieve that, we add the navigation parameter invoicePath
to the detail route in the app descriptor, so that we can hand over the information for the selected item to the detail page.
Mandatory navigation parameters are defined with curly brackets.
{
…
"sap.ui5": {
…
"routing": {
"config": {
"routerClass": "sap.m.routing.Router",
"type": "View",
"viewType": "XML",
"path": "ui5.walkthrough.view",
"controlId": "app",
"controlAggregation": "pages"
},
"routes": [
{
"pattern": "",
"name": "overview",
"target": "overview"
},
{
"pattern": "detail/{invoicePath}",
"name": "detail",
"target": "detail"
}
],
"targets": {
"overview": {
"id": "overview",
"name": "Overview"
},
"detail": {
"id": "detail",
"name": "Detail"
}
}
}
}
}
In the controller for the invoice list view, we extend the onPress
event handler in such a way it not only triggers the navigation to the detail view but also passes the selected item to the routing.
For that we have to pass the event object to our onPress
method. This way we get access to the information about the event that occurred. By calling th getSource
method we retrieve the source of the event. This method is available for all SAPUI5 events. In our case it will return the ObjectListItem
that has been clicked. We use it to pass the information of the clicked item to the detail page, so that the same item can be displayed there.
In the navTo
method we now add a configuration object to fill the navigation parameter invoicePath
with the current information of the item. This will update the URL and navigate to the detail view at the same time. On the detail page, we can access this navigation parameter again and display the corresponding item.
Typically we'd use the key of the item in the back-end system to identify the selected object, because it is short and precise. For our invoice items however, we do not have a simple key. Therefore, we directly use the binding path to keep the example short and simple. The path to the item is part of the binding context which is a helper object of SAPUI5 to manage the binding information for controls. The binding context can be accessed by calling the getBindingContext
method with the model name on any bound SAPUI5 control. We need to remove the first /
from the binding path by calling .substring(1)
on the string because this is a special character in URLs and is not allowed; we need to add it again on the detail page. Also, the binding path might contain special characters which are not allowed in URLs, so we have to encode the path with encodeURIComponent
.
import Controller from "sap/ui/core/mvc/Controller";
import JSONModel from "sap/ui/model/json/JSONModel";
import { SearchField$SearchEvent } from "sap/m/SearchField";
import Filter from "sap/ui/model/Filter";
import FilterOperator from "sap/ui/model/FilterOperator";
import ListBinding from "sap/ui/model/ListBinding";
import UIComponent from "sap/ui/core/UIComponent";
import Event from "sap/ui/base/Event";
import ObjectListItem from "sap/m/ObjectListItem";
/**
* @namespace ui5.walkthrough.controller
*/
export default class App extends Controller {
…
onPress(event: Event): void {
const item = event.getSource() as ObjectListItem;
const router = UIComponent.getRouterFor(this);
router.navTo("detail", {
invoicePath: window.encodeURIComponent(item.getBindingContext("invoice").getPath().substring(1))
});
}
};
Now we need to create a new detail controller to set the content we passed in with the URL parameter invoicePath
on the detail view. This will allow us to access the data of the selected item and display them on the view.
In addition to the (base) controller and our local component we import the Route$PatternMatchedEvent
type from sap/ui/core/routing/Route
. This event is triggered whenever a route pattern is matched, so we need it to catch any navigation with route pattern "detail/{invoicePath}".
In the onInit
method, we receive the router instance from the owner component and attach a listener to the details
route's "patternMatched" event by calling the method attachPatternMatched
. The onObjectMatched
method is the event handler for the "patternMatched" event. When the detail
route is matched, it will trigger the onObjectMatched
method.
In the onObjectMatched
method we bind the view's element to a specific path in the "invoice" model. We get the path from the invoicePath
argument from the event that was set in the invoice list controller. Because we have encoded the binding path part in the URL in the invoice list controller, we have to decode it again with decodeURIComponent
and also add the root `/` in front of the path again that was removed for passing the path as an URL parameter.
The bindElement
function creates a binding context for an SAPUI5 control and receives the model name as well as the path to an item in a configuration object. This will trigger an update of the UI controls that we connected with fields of the invoice model.
import Controller from "sap/ui/core/mvc/Controller";
import UIComponent from "sap/ui/core/UIComponent";
import { Route$PatternMatchedEvent } from "sap/ui/core/routing/Route";
/**
* @namespace ui5.walkthrough.controller
*/
export default class Detail extends Controller {
onInit(): void {
const router = UIComponent.getRouterFor(this);
router.getRoute("detail").attachPatternMatched(this.onObjectMatched, this);
}
onObjectMatched(event: Route$PatternMatchedEvent): void {
this.getView().bindElement({
path: "/" + window.decodeURIComponent( (event.getParameter("arguments") as any).invoicePath),
model: "invoice"
});
}
};
Our last piece to fit the puzzle together is the detail view. We replace the app controller by the new detail controller that will take care of setting the item's context on the view and bind the properties intro
and title
of the ObjectHeader
to ShipperName
and ProductName
of our invoice
model to display two fields of an invoice on the view. We could add more detailed information from the invoice
object here, but for simplicity reasons we just display two fields for now.
<mvc:View
controllerName="ui5.walkthrough.controller.Detail"
xmlns="sap.m"
xmlns:mvc="sap.ui.core.mvc">
<Page
title="{i18n>detailPageTitle}">
<ObjectHeader
intro="{invoice>ShipperName}"
title="{invoice>ProductName}"/>
</Page>
</mvc:View>
-
Define the routing configuration in the
manifest.json
/ app descriptor -
Initialize the router at the end of your
Component#init
function
Related Information
Tutorial: Navigation and Routing