In this step, we utilize the sap.f.routing.Router
.
Changing layouts based on the sap.f.routing.Router (no visual changes to last step)
You can view and download all files at Flexible Column Layout App - Step 7.
<mvc:View
controllerName="sap.ui.demo.fcl.controller.App"
displayBlock="true"
height="100%"
xmlns="sap.f"
xmlns:mvc="sap.ui.core.mvc">
<FlexibleColumnLayout
id="flexibleColumnLayout"
stateChange=".onStateChanged"
backgroundDesign="Solid"
layout="{/layout}"/>
</mvc:View>
We remove the hard-coded beginColumnPages
and endColumnPages
aggregations (since the router will add them automatically from now on), and we bind the layout
property so that it can be changed easily from the controller.
sap.ui.define([
"sap/ui/core/mvc/Controller"
], function (Controller) {
"use strict";
return Controller.extend("sap.ui.demo.fcl.controller.App", {
onInit: function () {
this.oOwnerComponent = this.getOwnerComponent();
this.oRouter = this.oOwnerComponent.getRouter();
this.oRouter.attachRouteMatched(this.onRouteMatched, this);
},
onRouteMatched: function (oEvent) {
var sRouteName = oEvent.getParameter("name"),
oArguments = oEvent.getParameter("arguments");
// Save the current route name
this.currentRouteName = sRouteName;
this.currentProduct = oArguments.product;
},
onStateChanged: function (oEvent) {
var bIsNavigationArrow = oEvent.getParameter("isNavigationArrow"),
sLayout = oEvent.getParameter("layout");
// Replace the URL with the new layout if a navigation arrow was used
if (bIsNavigationArrow) {
this.oRouter.navTo(this.currentRouteName, {layout: sLayout, product: this.currentProduct}, true);
}
},
onExit: function () {
this.oRouter.detachRouteMatched(this.onRouteMatched, this);
}
});
});
We access the router and bind to its routeMatched
event. For more information, see Router.
sap.ui.define([
"sap/ui/core/mvc/Controller",
"sap/ui/model/Filter",
"sap/ui/model/FilterOperator",
"sap/ui/model/Sorter",
"sap/m/MessageBox",
"sap/f/library"
], function (Controller, Filter, FilterOperator, Sorter, MessageBox, fioriLibrary) {
"use strict";
return Controller.extend("sap.ui.demo.fcl.controller.List", {
onInit: function () {
this.oView = this.getView();
this._bDescendingSort = false;
this.oProductsTable = this.oView.byId("productsTable");
this.oRouter = this.getOwnerComponent().getRouter();
},
onSearch: function (oEvent) {
var oTableSearchState = [],
sQuery = oEvent.getParameter("query");
if (sQuery && sQuery.length > 0) {
oTableSearchState = [new Filter("Name", FilterOperator.Contains, sQuery)];
}
this.oProductsTable.getBinding("items").filter(oTableSearchState, "Application");
},
onAdd: function () {
MessageBox.information("This functionality is not ready yet.", {title: "Aw, Snap!"});
},
onSort: function () {
this._bDescendingSort = !this._bDescendingSort;
var oBinding = this.oProductsTable.getBinding("items"),
oSorter = new Sorter("Name", this._bDescendingSort);
oBinding.sort(oSorter);
},
onListItemPress: function (oEvent) {
var productPath = oEvent.getSource().getBindingContext("products").getPath(),
product = productPath.split("/").slice(-1).pop();
this.oRouter.navTo("detail", {layout: fioriLibrary.LayoutType.TwoColumnsMidExpanded, product: product});
}
});
});
We change the event handler for pressing an item from the list view to use the router instead of manually manipulating the FlexibleColumnLayout
instance. When we call the router's navTo
method, the router itself will change the layout
property of the FlexibleColumnLayout
.
sap.ui.define([
"sap/ui/core/mvc/Controller"
], function (Controller) {
"use strict";
return Controller.extend("sap.ui.demo.fcl.controller.Detail", {
onInit: function () {
var oOwnerComponent = this.getOwnerComponent();
this.oRouter = oOwnerComponent.getRouter();
this.oModel = oOwnerComponent.getModel();
this.oRouter.getRoute("list").attachPatternMatched(this._onProductMatched, this);
this.oRouter.getRoute("detail").attachPatternMatched(this._onProductMatched, this);
},
_onProductMatched: function (oEvent) {
this._product = oEvent.getParameter("arguments").product || this._product || "0";
this.getView().bindElement({
path: "/ProductCollection/" + this._product,
model: "products"
});
},
onEditToggleButtonPress: function() {
var oObjectPage = this.getView().byId("ObjectPageLayout"),
bCurrentShowFooterState = oObjectPage.getShowFooter();
oObjectPage.setShowFooter(!bCurrentShowFooterState);
},
onExit: function () {
this.oRouter.getRoute("list").detachPatternMatched(this._onProductMatched, this);
this.oRouter.getRoute("detail").detachPatternMatched(this._onProductMatched, this);
}
});
});
We bind the table in the detail view to reflect the currently selected product from the list view.
sap.ui.define([
'sap/ui/core/UIComponent',
'sap/ui/model/json/JSONModel',
'sap/f/library'
], function(UIComponent, JSONModel, fioriLibrary) {
'use strict';
return UIComponent.extend('sap.ui.demo.fcl.Component', {
metadata: {
manifest: 'json'
},
init: function () {
var oModel,
oProductsModel,
oRouter;
UIComponent.prototype.init.apply(this, arguments);
oModel = new JSONModel();
this.setModel(oModel);
// set products demo model on this sample
oProductsModel = new JSONModel(sap.ui.require.toUrl('sap/ui/demo/mock/products.json'));
oProductsModel.setSizeLimit(1000);
this.setModel(oProductsModel, 'products');
oRouter = this.getRouter();
oRouter.attachBeforeRouteMatched(this._onBeforeRouteMatched, this);
oRouter.initialize();
},
_onBeforeRouteMatched: function(oEvent) {
var oModel = this.getModel(),
sLayout = oEvent.getParameters().arguments.layout;
// If there is no layout parameter, set a default layout (normally OneColumn)
if (!sLayout) {
sLayout = fioriLibrary.LayoutType.OneColumn;
}
oModel.setProperty("/layout", sLayout);
}
});
});
We initialize the router and bind to its onBeforeRouteMatched
event, and we introduce a model, which will be used for the layout.
{
"_version": "1.38.0",
"sap.app": {
"id": "sap.ui.demo.fcl",
"type": "application",
"applicationVersion": {
"version": "1.0.0"
}
},
"sap.ui5": {
"rootView": {
"viewName": "sap.ui.demo.fcl.view.App",
"type": "XML",
"async": true,
"id": "fcl"
},
"dependencies": {
"minUI5Version": "1.98.0",
"libs": {
"sap.f": {},
"sap.m": {},
"sap.ui.core": {},
"sap.uxap": {}
}
},
"routing": {
"config": {
"routerClass": "sap.f.routing.Router",
"type": "View",
"viewType": "XML",
"path": "sap.ui.demo.fcl.view",
"controlId": "flexibleColumnLayout",
"transition": "slide",
"bypassed": {
},
"async": true
},
"routes": [
{
"pattern": ":layout:",
"name": "list",
"target": [
"list",
"detail"
]
},
{
"pattern": "detail/{product}/{layout}",
"name": "detail",
"target": [
"list",
"detail"
]
}
],
"targets": {
"list": {
"name": "List",
"controlAggregation": "beginColumnPages"
},
"detail": {
"name": "Detail",
"controlAggregation": "midColumnPages"
}
}
}
}
}
Finally, we add the routing configuration in the manifest.json
.