In this post I want to introduce the new module concept of SAPUI5/OpenUI5 which is propagated since version 1.28 of UI5. I will explain this with the help of WebStorm UI5 file templates, which will follow this new UI5 module approach and can be used for development custom Fiori apps.
Some words to WebStorm. WebStorm is one of the best IDE for web development (JetBRAINS is able to charge money for it, but still it is very cheap and in my opinion a good investment). And by the way SAP Web IDE is also not free for productive usage, at least up to now. With the following UI5 File Templates it is quite handy and quick to create custom Fiori applications based on the new module concept.
With version 1.28 of SAPUI5/OpenUI5 a new module concept is propagated. In the core classes of SAPUI5 it is already used much longer. The code templates which will be introduced below will be based in this concept.
AMD (Asynchronous Module Definition) is designed to allow asynchronous loading of JavaScript modules (with this name not very surprising) in browsers. It is also the API which is supported by RequireJS. So SAP is following a well-established and accepted standard in the web, this is a good direction and will continue to make it a success.
In UI5 this is realised with sap.ui.define to define new modules and with sap.ui.require to resolve module dependencies. To understand usage, let’s have a look at some file template examples:
File templates can be created in WebStorm via Preferences->Editor->File and Code Templates (in WebStorm 10 with a open project):
Via + (Plus sign) you can create a new Template. Specifiy a name and a extension and use placeholders with ${} syntax. As placeholder we will use ${UI5_Namespace} for the UI5 component namespace and ${NAME} for file name.
Let’s start with controller file:
Template Name | Extension |
---|---|
UI5 Controller | controller.js |
sap.ui.define([
"sap/ui/core/mvc/Controller"
], function (Controller) {
"use strict";
return Controller.extend("${UI5_Namespace}.controller.${NAME}", {
onInit: function () {
this.component = this.getOwnerComponent();
this.bus = this.component.getEventBus();
this.router = sap.ui.core.UIComponent.getRouterFor(this);
}
});
});
So what kind of structure do we facing, if using the new AMD concept:
Template Name | Extension |
---|---|
UI5 XML View | view.xml |
<mvc:View
controllerName="${UI5_Namespace}.controller.${NAME}"
xmlns="sap.m"
xmlns:l="sap.ui.layout"
xmlns:f="sap.ui.layout.form"
xmlns:core="sap.ui.core"
xmlns:mvc="sap.ui.core.mvc">
<Page title="${NAME}"
navButtonPress="onNavBack"
showNavButton="true">
<content>
</content>
<footer>
<Bar>
</Bar>
</footer>
</Page>
</mvc:View>
XML Views are as before, only we put the placeholders in, so that it is working as file template within WebStorm.
Template Name | Extension |
---|---|
UI5 Component | js |
sap.ui.define([
"sap/ui/core/UIComponent",
"sap/ui/model/resource/ResourceModel"
], function (UIComponent, ResourceModel) {
"use strict";
return UIComponent.extend("${UI5_Namespace}.Component", {
metadata: {
"rootView": "${UI5_Namespace}.view.App",
"dependencies": {
"minUI5Version": "1.28.0",
"libs": ["sap.ui.core", "sap.m", "sap.ui.layout"]
},
"config": {
"i18nBundle": "${UI5_Namespace}.i18n.i18n",
"serviceUrl": "here/goes/your/serviceUrl/"
},
"routing": {
"config": {
"routerClass": "sap.m.routing.Router",
"viewType": "XML",
"viewPath": "${UI5_Namespace}.view",
"controlId": "idAppControl",
"controlAggregation": "detailPages",
"bypassed": {
"target": ["master", "notFound"]
}
},
"routes": [
{
"pattern": "",
"name": "master",
"target": ["detail", "master"]
},
{
"pattern": "detail/{detailId}",
"name": "detail",
"target": ["master", "detail"]
}
],
"targets": {
"master": {
"viewName": "Master",
"viewLevel": 1,
"viewId": "master",
"controlAggregation": "masterPages"
},
"detail": {
"viewName": "Detail",
"viewId": "detail",
"viewLevel": 2
},
"notFound": {
"viewName": "NotFound",
"viewId": "notFound",
"viewLevel": 3
}
}
}
},
init: function () {
var mConfig = this.getMetadata().getConfig();
// set the internationalization model
this.setModel(new ResourceModel({
bundleName: mConfig.i18nBundle
}), "i18n");
// call the base component's init function and create the App view
UIComponent.prototype.init.apply(this, arguments);
// create the views based on the url/hash
this.getRouter().initialize();
},
destroy: function () {
// call the base component's destroy function
UIComponent.prototype.destroy.apply(this, arguments);
}
});
});
This is a component file template for a master-detail application.
In the Component the App View is referenced as rootView. For master-detail application the SplitApp is used, let’s create another File Template „UI5 SplitApp“ (extension: view.xml) for this:
Template Name | Extension |
---|---|
UI5 SplitApp | view.xml |
<mvc:View
controllerName="ui5v128.controller.App"
xmlns="sap.m"
xmlns:mvc="sap.ui.core.mvc">
<SplitApp id="idAppControl" displayBlock="true"/>
</mvc:View>
And finally we create a index.html file for local testing:
Template Name | Extension |
---|---|
UI5 index.html | html |
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
<meta charset="UTF-8">
<title>UI5 App</title>
<script id="sap-ui-bootstrap"
src="https://openui5.hana.ondemand.com/resources/sap-ui-core.js"
data-sap-ui-libs="sap.m"
data-sap-ui-theme="sap_bluecrystal"
data-sap-ui-preload="async"
data-sap-ui-compatVersion="edge"
data-sap-ui-resourceroots='{"${UI5_Namespace}": "./"}'
data-sap-ui-frameOptions='allow'> // NON-SECURE setting for testing environment
</script>
<script>
sap.ui.getCore().attachInit(function () {
sap.ui.require([
"sap/ui/core/ComponentContainer",
"${UI5_Namespace}/Component"
], function (ComponentContainer, Component) {
new sap.ui.core.ComponentContainer({
name: "${UI5_Namespace}"
}).placeAt('root');
});
});
</script>
</head>
<body class="sapUiBody" id="root">
</body>
</html>
This is an example how to use sap.ui.require and load necessary dependencies. The structure is somehow identically to the sap.ui.require usage. In the first parameter (array of strings) the necessary dependencies are listed, which are passed as parameters to the callback function.
Now we ready to go and create a custom Fiori application.
Now we want to use the new file templates within WebStorm (of course you can use these templates also without WebStorm)
Create an empty project and two folders (the given templates assume this kind of directory structure):
We want to create a master view and a detail view.
Therefore select the view folder and right-click and select New and select the UI5 XML View template:
Enter as File name „Master“ and as UI5 namespace „ui5v128″ (you can also use your own namespace):
For the controller select controller folder and and right-click and select New and select the UI5 Controller template. Enter again as File name „Master“ and as UI5 namespace „ui5v128″:
Repeat this for the Detail view/controller (File Name „Detail“,UI5 namespace „ui5v128″).
Additionally we will need the SplitApp View. Please name it „App“ and select the „UI5 SplitApp“ Template (again UI5 namespace „ui5v128″).
If you follow this convention the given UI5 Component template will fit, this is is our last step.
Create a UI5 Component (file name: Component) and index.html file (file name index) in the project root folder, both with the same UI5 namespace „ui5v128″. The result should look like this:
Within WebStorm you can directly run the App via the index.html file. Right-click the index.html and select Run ‚index.html‘:
The working app is more or less empty, but uses the new module structure. So you prepared for the future (v1.30) and now it is up to you to fill it with more content.
Have fun with SAPUI5 and AMD concept and migrating Fiori Apps.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
User | Count |
---|---|
8 | |
5 | |
5 | |
4 | |
4 | |
4 | |
4 | |
4 | |
3 | |
3 |