Display Data from the Northwind Service
- How to use a sub-generator to add an OData model to the SAPUI5 application
- How to navigate between SAPUI5 views
- How to configure UI5 tooling tasks
Prerequisites
- You have previously created a SAPUI5 based project, e.g. with the easy-ui5 generator.
- Step 1
Newer versions of the easy-ui5 generator create projects that contain two views out of the box: The
App.view.xml
, which is the outer container of the application, and theMainView.view.xml
, where you can start developing your application content right away. At this point, it makes sense to rename theMainView.view.xml
to something more meaningful.- Rename the file
MainView.view.xml
toProducts.view.xml
. - In the
Products.view.xml
file, replace all references toMainView
withProducts
. - Rename the file
MainView.controller.js
toProducts.controller.js
. - In the
Products.controller.js
file, replace all references toMainView
withProducts
. - In the
manifest.json
file, replace all references toMainView
withProducts
.
- Rename the file
- Step 2
Replace the current content of the
Products.view.xml
with a page that contains one list that uses an aggregation binding.```XML [4-10] <mvc:View controllerName="tutorial.products.controller.Products" displayBlock="true" xmlns="sap.m" xmlns:mvc="sap.ui.core.mvc"> <Page id="Products" title="Available Products"> <content> <List items="{/Products}"> <StandardListItem type="Active" title="{ProductName}" /> </List> </content> </Page> </mvc:View> ```
You’ll immediately be able to see that the
App.view.xml
embeds theProducts.view.xml
and displays an empty list. The list is still empty, because there is not data source bound to the application yet. - Step 3
To populate the list with items, bind a data source to the application. For this, there exists another sub-generator:
You can find a list of all available sub-generators on GitHub.
TerminalCopyyo easy-ui5 project newmodel
Parameter Value What is the name of your model, press enter if it is the default model? keep blank Which type of model do you want to add? OData v2
Which binding mode do you want to use? TwoWay
What is the data source URL? V2/Northwind/Northwind.svc/
Which count mode do you want to use? Inline
Again, please accept the modification of the manifest file.
The generator will name the data source based on the URL you specified. You can replace the name in the
manifest.json
if you don’t like it. - Step 4
-
All requests to the data source will be sent to
<webapp URL>/V2/Northwind/Northwind.svc/
.Modify the
uimodule/webapp/xs-app.json
file to redirect the traffic to a destination. Also, turn off the authentication and replace the entire file with the following content.JSONCopy{ "welcomeFile": "/index.html", "routes": [ { "source": "^/V2/(.*)$", "authenticationType": "none", "destination": "Northwind", "csrfProtection": false }, { "source": "^(.*)", "target": "$1", "authenticationType": "xsuaa", "service": "html5-apps-repo-rt" } ] }
-
You already created a destination named “Northwind” in Cloud Foundry environment of SAP BTP. Now it’s time to add a mocked destination to your local setup as well.
Replace the empty array of the property
destinations
in theuimodule/ui5.yaml
file to declare the local destination.YAMLCopydestinations: - name: "Northwind" url: "https://services.odata.org/"
YAML is quite nice to read but writing can be cumbersome as the indention of the lines is crucial. Please make sure your file looks exactly as shown in the next screenshot. If you edit these files often, I recommend using IDE plugins to make your life easier like this one to validate the format
-
Switch to the first terminal session, stop the process and restart it. Restarting is necessary because the live-reload feature doesn’t notice changes in the
ui5.yaml
file.
TerminalCopy<ctrl + c> npm start
Alternatively, you can directly invoke
npx ui5 serve -o test/flpSandbox.html
, which is equivalent tonpm start
or runnpx ui5 serve
, the later one won’t open a new page in the browser.Now you should see the Northwind products in the SAPUI5 list control:
-
- Step 5
In this step, you will add a detail page that shows some additional information. You will use an easy-ui5 sub-generator to create a new view.
Switch back to the second terminal session and run the same sub-generator as before.
TerminalCopyyo easy-ui5 project newview
Parameter Value What is the name of the new view? ProductDetail
Would you like to create a corresponding controller as well? Yes
Do you want to add an OPA5 page object? No
Would you like to create a route in the manifest? Yes
Once again, accept that the generator can overwrite the
manifest.json
file.Open the
uimodule/webapp/manifest.json
file and add the product ID to the pattern of the newly created routeProductDetail
.JSONCopy{ "name": "ProductDetail", "pattern": "Product/{productId}", "target": [ "TargetProductDetail" ] }
Change the type of the list items and an event listener in the
uimodule/webapp/view/Products.view.xml
file.XMLCopy<StandardListItem type="Navigation" press="handleListItemPress" title="{ProductName}" />
Add navigation logic to the
uimodule/webapp/controller/Products.controller.js
to handle the press event.JavaScriptCopysap.ui.define([ "tutorial/products/controller/BaseController" ], function (Controller) { "use strict"; return Controller.extend("tutorial.products.controller.Products", { handleListItemPress: function (oEvent) { var oRouter = sap.ui.core.UIComponent.getRouterFor(this); var selectedProductId = oEvent.getSource().getBindingContext().getProperty("ProductID"); oRouter.navTo("ProductDetail", { productId: selectedProductId }); } }); });
Click on any list item. This should trigger a navigation to a new page.
- Step 6
Add controller logic to
uimodule/webapp/controller/ProductDetail.controller.js
to parse selected product from the routing arguments and to bind the product to the view.JavaScriptCopysap.ui.define([ "tutorial/products/controller/BaseController" ], function(Controller) { "use strict"; return Controller.extend("tutorial.products.controller.ProductDetail", { onInit: function () { const oRouter = sap.ui.core.UIComponent.getRouterFor(this); oRouter.getRoute("ProductDetail").attachMatched(this._onRouteMatched, this); }, _onRouteMatched: function (oEvent) { const iProductId = oEvent.getParameter("arguments").productId; const oView = this.getView(); oView.bindElement({ path: "/Products(" + iProductId + ")", events: { dataRequested: function () { oView.setBusy(true); }, dataReceived: function () { oView.setBusy(false); } } }); }, }); });
Add the required declarations to the
uimodule/webapp/view/ProductDetail.view.xml
view to display some properties.XMLCopy<mvc:View controllerName="tutorial.products.controller.ProductDetail" displayBlock="true" xmlns="sap.m" xmlns:mvc="sap.ui.core.mvc"> <Page id="ProductDetail" title="Detail Page"> <VBox> <Text text="{ProductName}" /> <Text text="{UnitPrice}" /> <Text text="{QuantityPerUnit}" /> <Text text="{UnitsInStock}" /> </VBox> </Page> </mvc:View>
Once you saved the view, the web app should update automatically and display a view similar to this this one.
Which title do you see on the page you just navigated to?