DAT375 SupportingMaterial
DAT375 SupportingMaterial
SAP HANA
DAT375
Exercises / Solutions
Rich Heilman, SAP Labs, LLC.
Thomas Jung, SAP Labs, LLC.
Uri Nizan, SAP Labs Israel Ltd.
Sushma Prabhakar, SAP LABS INDIA PVT. LTD.
Nachshon Vagmayster, SAP Labs Israel Ltd.
DAT375
TABLE OF CONTENTS
BEFORE YOU START ......................................................................................................................................3
Getting Help .....................................................................................................................................................3
Source Code Solutions ....................................................................................................................................3
EXERCISE 1 – HELLO WORLD ........................................................................................................................4
EXERCISE 1 – SOLUTION................................................................................................................................5
Exercise 1.1: HTML5 Module - Hello World.....................................................................................................5
EXERCISE 2 –DATABASE ARTIFACT DEVELOPMENT................................................................................13
EXERCISE 2 – SOLUTION..............................................................................................................................14
Exercise 2.1: Database Content ....................................................................................................................14
Exercise 2.2: Create Tables & Views via Core Data Services ......................................................................20
Exercise 2.3: Table Data Configuration ........................................................................................................27
Exercise 2.4: Create Structured Privilege & Role .........................................................................................31
Exercise 2.5: Non-Container Schemas, User Provided Services & Synonyms...........................................34
Exercise 2.6: Cross Container Services & Synonyms .................................................................................43
Exercise 2.7: Creating a Graphical Calculation View ...................................................................................48
Exercise 2.8: Stored Procedure.....................................................................................................................56
EXERCISE 3 –XSJS AND XSODATA SERVICES ...........................................................................................61
EXERCISE 3 – SOLUTION..............................................................................................................................62
Exercise 3.1: XSJS and XSODATA ................................................................................................................62
Exercise 3.2: Creating an OData Service with Create Operation and XSJS Exit .........................................72
EXERCISE 4 – NODE.JS ................................................................................................................................75
EXERCISE 4 – SOLUTION..............................................................................................................................76
Exercise 4.1: Modules and Express ..............................................................................................................76
Exercise 4.2: HANA Database Access from Node.js ....................................................................................83
EXERCISE 5 – SAPUI5 USER INTERFACE....................................................................................................88
EXERCISE 5 – SOLUTION..............................................................................................................................89
Exercise 5.1: SAPUI5 as an XSA Service Broker ..........................................................................................89
Exercise 5.2: SAPUI5 User Interface .............................................................................................................92
EXERCISE 6 – PACKAGING FOR TRANSPORT.......................................................................................... 108
EXERCISE 6 – SOLUTION ............................................................................................................................ 109
Exercise 6.1: Package for Transport ........................................................................................................... 109
2
DAT375
Getting Help
If you need addition help resources beyond this document, we would suggest the following content:
• The Online Help at https://help.sap.com/viewer/4505d0bdaf4948449b7f7379d24d0f0d/2.0.01/en-US
All source code solutions and templates for all exercises in this document can be found in the following
webpage.
https://github.com/jungsap/TechEd2018.DAT375/tree/snippets/
In some cases, it might be a little easier to copy and paste the coding instead of typing it all manually. If
copying/pasting, I would suggest that you make sure to understand what is being copied/pasted before moving
on.
You can also view the completed workshop with a sample solution here:
https://github.com/jungsap/TechEd2018.DAT375/tree/master
3
DAT375
Objective
In this first exercise, we will connect to the remote system, run the new project wizard, and then create an HTML5
module to serve as the application endpoint and proxy all our services and client-side content. At the end of this
exercise you will be able to connect to your server via web browser and see a Hello World message.
4
DAT375
EXERCISE 1 – SOLUTION
Explanation Screenshot
https://wdflbmt0794.wdf.sa
p.corp:53075/
User: DAT375
Password:
WelcomeSAP2018
5
DAT375
4. Choose Multi-Target
Application Project and
then press Next.
6
DAT375
7
DAT375
8
DAT375
value helps.
9
DAT375
xs create-service xsuaa
space <service name>
10
DAT375
11
DAT375
Authentication at the XS
level is now done by
referencing a user store.
This can be configured to
be the HANA database or it
can be an external user
directory.
12
DAT375
Objective
In this exercise, we will continue to develop our overall application. Applications in the HANA/XS Advanced
world, are often made up of multiple modules at design time which deploy to separate micro-services or
database container content. We created client-side UI application content in the first exercise using the HTML5
module. In this exercise, we will create database artifacts, such as database table, stored procedures and user
defined functions, using the HDB (HANA Database) module. We will then see how we build these database
artifacts using the new container-based, schema-less HDI (HANA Deployment Infrastructure) concepts.
Exercise Description
13
DAT375
EXERCISE 2 – SOLUTION
Explanation Screenshot
14
DAT375
15
DAT375
16
DAT375
TARGET_CONTAINER to
describe it as the primary
database resource for this
module.
properties:
TARGET_CONTAINER:
~{hdi-container-name}
17
DAT375
18
DAT375
19
DAT375
Exercise 2.2: Create Tables & Views via Core Data Services
In this exercise, you will create a Purchase Order header and item table as well as a view over those two tables
using Core Data Services(CDS).
Explanation Screenshot
20
DAT375
21
DAT375
TAXAMOUNT : AmountT;
@Comment : 'Lifecycle Status'
LIFECYCLESTATUS : StatusT;
@Comment : 'Approval Status'
APPROVALSTATUS : StatusT;
@Comment : 'Confirmation Status'
CONFIRMSTATUS : StatusT;
@Comment : 'Ordering Status'
ORDERINGSTATUS : StatusT;
@Comment : 'Invoicing Status'
INVOICINGSTATUS : StatusT;
}
technical configuration {
column store;
};
22
DAT375
CURRENCY as "CurrencyCode",
GROSSAMOUNT as "Amount",
NETAMOUNT as "NetAmount",
TAXAMOUNT as "TaxAmount",
QUANTITY as "Quantity",
QUANTITYUNIT as "QuantityUnit",
DELIVERYDATE as "DeliveryDate1"
}
with structured privilege check;
};
23
DAT375
@Comment : 'Notes'
NOTEID : BusinessKey null;
@Comment : 'Supplier'
PARTNER : BusinessKey;
@Comment : 'Currency'
CURRENCY : CurrencyT;
24
DAT375
11.Right-click on the
PurchaseOrder.Header table
and choose Open
25
DAT375
26
DAT375
Explanation Screenshot
27
DAT375
"ORDERINGSTATUS",
"INVOICINGSTATUS"]
},
"column_mappings": {
"PURCHASEORDERID": 1,
"NOTEID": 6,
"PARTNER": 7,
"CURRENCY": 8,
"GROSSAMOUNT": 9,
"NETAMOUNT": 10,
"TAXAMOUNT": 11,
"LIFECYCLESTATUS": 12,
"APPROVALSTATUS": 13,
"CONFIRMSTATUS": 14,
"ORDERINGSTATUS": 15,
"INVOICINGSTATUS": 16
}
},
{
"target_table": "PurchaseOrder.Item",
"source_data": {
"data_type": "CSV",
"file_name": "item.csv",
"has_header": false,
"dialect": "HANA",
"type_config": {
"delimiter": ","
}
},
"import_settings": {
"import_columns":
["POHeader.PURCHASEORDERID",
"PRODUCT",
"NOTEID",
"CURRENCY",
"GROSSAMOUNT",
"NETAMOUNT",
"TAXAMOUNT",
"QUANTITY",
"QUANTITYUNIT" ]
},
"column_mappings": {
"POHeader.PURCHASEORDERID": 1,
"PRODUCT": 3,
"NOTEID": 4,
"CURRENCY": 5,
"GROSSAMOUNT": 6,
"NETAMOUNT": 7,
"TAXAMOUNT": 8,
"QUANTITY": 9,
"QUANTITYUNIT": 10
28
DAT375
}]
}
29
DAT375
0500000001,0000000060,HT-
1002,,USD,3736.6,3140,596.6,2,EA,20121204
0500000001,0000000070,HT-
1100,,USD,320.94,269.7,51.24,3,EA,20121204
0500000001,0000000080,HT-
2026,,USD,107.06,89.97,17.09,3,EA,20121204
0500000001,0000000090,HT-
1002,,USD,3736.6,3140,596.6,2,EA,20121204
0500000001,0000000100,HT-
1100,,USD,320.94,269.7,51.24,3,EA,20121204
30
DAT375
Explanation Screenshot
31
DAT375
https://github.com/jungsap/Te
chEd2018.DAT375/blob/snip
pets/ex2/ex2_5
}
}
32
DAT375
33
DAT375
Explanation Screenshot
34
DAT375
35
DAT375
5. Click Save
36
DAT375
9. Click Save
https://github.com/jungsap/Tec
hEd2018.DAT375/blob/snippet
s/ex2/ex2_11
37
DAT375
https://github.com/jungsap/Tec
hEd2018.DAT375/blob/snippet
s/ex2/ex2_11
https://github.com/jungsap/Tec
hEd2018.DAT375/blob/snippet
s/ex2/ex2_11
38
DAT375
};
39
DAT375
https://github.com/jungsap/Tec
hEd2018.DAT375/blob/snippet
s/ex2/ex2_12
40
DAT375
41
DAT375
42
DAT375
In this exercise, we will configure access and synonyms between our local project container and an already
existing container deployed on this system.
Explanation Screenshot
43
DAT375
https://github.com/jungsap/
TechEd2018.DAT375/blob/
snippets/ex2/ex2_13a
44
DAT375
5. Click Save
45
DAT375
BusinessPartners =
MD.BusinessPartner
Products =
core.models::PRODUCTS
9. Click Save
46
DAT375
47
DAT375
Explanation Screenshot
48
DAT375
Click “Create”.
49
DAT375
8) Add
PurchaseOrder.ItemView
to the node and then press
Finish.
50
DAT375
51
DAT375
52
DAT375
Select
PurchaseOrderItemId,
ProductID, Amount,
Quantity, Product_Category,
Product_Description, and
Product_Name and then
choose Add To Output.
53
DAT375
54
DAT375
55
DAT375
Explanation Screenshot
56
DAT375
57
DAT375
:ex_products.(PRICE).UPDATE((:ex_products.PRICE[lv_index
] * 1.25), lv_index);
END FOR;
:ex_products.DELETE(:lv_del_index);
END
58
DAT375
59
DAT375
60
DAT375
Objective
For this exercise, we will now build the XSJS and XSODATA services used to expose our data model to the user
interface. Although XS Advanced runs on node.js, SAP has added modules to node.js to provide XSJS and
XSODATA backward compatibility. Therefore, you can use the same programming model and much of the same
APIs from XS, classic even within this new environment.
Exercise Description
61
DAT375
EXERCISE 3 – SOLUTION
Explanation Screenshot
62
DAT375
63
DAT375
64
DAT375
"default": "$XSAPPNAME.Display"
}
}, {
"source": "(.*)(.xsodata)",
"destination": "xsjs_api",
"authenticationType": "xsuaa",
"scope": {
"GET": "$XSAPPNAME.Display",
"POST": [
"$XSAPPNAME.Display",
"$XSAPPNAME.Create"
],
"PUT": [
"$XSAPPNAME.Display",
"$XSAPPNAME.Create"
],
"DELETE": [
"$XSAPPNAME.Display",
"$XSAPPNAME.Delete"
],
"default": "$XSAPPNAME.Display"
}
}]
}
65
DAT375
come from the HDI container // anonymous : true, // remove to authenticate calls
which we bound to this service redirectUrl : "/index.xsjs"
via the mta.yaml file. };
66
DAT375
9. In the lib folder, create a sub- /*eslint no-console: 0, no-unused-vars: 0, no-shadow: 0, new-
folder called xsjs. Create a cap: 0*/
file named hdb.xsjs. Here is /*eslint-env node, es6 */
the source code for this file. "use strict";
67
DAT375
default:
$.response.status =
$.net.http.INTERNAL_SERVER_ERROR;
$.response.setBody("Invalid Request Method");
}
68
DAT375
16. /xsjs/exercisesMaster.xsjs
shows the typical approach to
have multiple REST actions
in one XSJS. Change the
URL to
/xsjs/exercisesMaster.xsjs?
cmd=getSessionInfo. You
should see your User Name
returned from the XSJS
session layer.
17./xsodata/purchaseOrder.xso
data?$format=json gives you
access to a full OData service
for the Purchase Order header
and item tables we created in
the previous exercise.
69
DAT375
70
DAT375
71
DAT375
Exercise 3.2: Creating an OData Service with Create Operation and XSJS Exit
Explanation Screenshot
72
DAT375
pStmt = param.connection.prepareStatement(
`INSERT INTO "PurchaseOrder.Header"
("HISTORY.CREATEDAT",
"HISTORY.CHANGEDAT", "HISTORY.CREATEDBY",
"HISTORY.CHANGEDBY", PARTNER,
NOTEID, CURRENCY, GROSSAMOUNT,
NETAMOUNT, TAXAMOUNT, LIFECYCLESTATUS, APPROVALSTATUS,
CONFIRMSTATUS, ORDERINGSTATUS, INVOICINGSTATUS )
values(now(), now(), null, null, '100000000', null,
'EUR', 100, 100, 100, 'N', 'I', 'I', 'I', 'I' )`
);
pStmt.executeUpdate();
pStmt.close();
} catch (e) {
$.trace.error(e.toString());
throw e;
}
}
73
DAT375
74
DAT375
EXERCISE 4 – NODE.JS
Objective
In exercise 3 we created a Node.js module, but didn’t do much Node.js specific programming. We only were
using Node.js to run XSJS and XSODATA services. The support for XSJS and XSODATA is an important
feature for XS Advanced. It not only allows backward compatible support for much of your existing development;
but it provides a simplified programming model as an alternative to the non-block I/O event driven programming
model normally used by Node.js.
But we certainly aren’t limited to only the functionality provided by XSJS and XSODATA. We have access to the
full programming model of Node.js as well. In this exercise, we will learn how to extend our existing Node.js
module in the SAP Web IDE for SAP HANA.
You will learn about how to create and use reusable code in the form of node.js modules. You will use
package.json to define dependencies to these modules which make the installation of them quite easy. You will
use one of the most popular modules – express; which helps with the setup the handling of the request and
response object. You will use express to handle multiple HTTP handlers in the same service by using routes.
Exercise Description
• Modules
• Express Module and package.json
• Local Modules
• SAP HANA database access from node.js
75
DAT375
EXERCISE 4 – SOLUTION
Explanation Screenshot
- name: js
76
DAT375
type: nodejs
path: js
provides:
- name: js_api
properties:
url: '${default-url}'
requires:
- name: dat375-uaa
- name: hdi_db
- name: db
- name: js_api
group: destinations
properties:
name: js_api
url: '~{url}'
forwardAuthToken: true
77
DAT375
//Setup Routes
var router = require("./router")(app, server);
78
DAT375
8. Add the following code to your /*eslint no-console: 0, no-unused-vars: 0, no-shadow: 0, new-
myNode.js file. This will add a cap: 0*/
simple GET handler that /*eslint-env node, es6 */
returns a “Hello World” "use strict";
message when requested. var express = require("express");
https://github.com/jungsap/Tec
79
DAT375
hEd2018.DAT375/blob/snippet
s/ex4/ex4_5
https://github.com/jungsap/Tec
hEd2018.DAT375/blob/snippet
s/ex4/ex4_6
80
DAT375
},{
"source": "(.*)(.xsjs)",
"destination": "xsjs_api",
"csrfProtection": true,
"authenticationType": "xsuaa",
"scope": {
"GET": "$XSAPPNAME.Display",
"POST": [
"$XSAPPNAME.Display",
"$XSAPPNAME.Create"
],
"PUT": [
"$XSAPPNAME.Display",
"$XSAPPNAME.Create"
],
"DELETE": [
"$XSAPPNAME.Display",
"$XSAPPNAME.Delete"
],
"default": "$XSAPPNAME.Display"
}
}, {
"source": "(.*)(.xsodata)",
"destination": "xsjs_api",
"authenticationType": "xsuaa",
"scope": {
"GET": "$XSAPPNAME.Display",
"POST": [
"$XSAPPNAME.Display",
"$XSAPPNAME.Create"
],
"PUT": [
"$XSAPPNAME.Display",
"$XSAPPNAME.Create"
],
"DELETE": [
"$XSAPPNAME.Display",
"$XSAPPNAME.Delete"
],
"default": "$XSAPPNAME.Display"
}
}]
}
81
DAT375
82
DAT375
Explanation Screenshot
2. Now add a new route for /*eslint no-console: 0, no-unused-vars: 0, no-shadow: 0, new-
/example1 that gets the cap: 0*/
database connection/client /*eslint-env node, es6 */
from the express request "use strict";
object (req.db). Then create a var express = require("express");
prepared statement for the
SELECT of SESSION_USER module.exports = function() {
from dummy. Execute the var app = express.Router();
statement and send the
results as JSON in the app.get("/", (req, res) => {
response object. return
res.type("text/plain").status(200).send("Hello World Node.js");
Note: if you don’t want to type });
this code, we recommend that
you cut and paste it from this app.get("/example1", (req, res) => {
web address var scope =
https://github.com/jungsap/Tec `${req.authInfo.xsappname}.Display`;
hEd2018.DAT375/blob/snippet if (req.authInfo &&
s/ex4/ex4_8 !req.authInfo.checkScope(scope)) {
return
res.type("text/plain").status(403).send("Forbidden");
}
83
DAT375
}
statement.exec([],
(err, results) => {
if (err) {
return
res.type("text/plain").status(500).send(`ERROR:
${err.toString()}`);
} else {
var
result = JSON.stringify({
Objects: results
});
return
res.type("application/json").status(200).send(result);
}
});
return null;
});
return null;
});
return app;
};
84
DAT375
out.push([item.PRODUCTID, item.CATEGORY,
item.PRICE]);
}
var excel = require("node-
xlsx");
var excelOut = excel.build([{
85
DAT375
name: "Products",
data: out
}]);
res.header("Content-
Disposition", "attachment; filename=Excel.xlsx");
return
res.type("application/vnd.ms-
excel").status(200).send(excelOut);
});
return null;
});
});
86
DAT375
87
DAT375
Objective
For this exercise, we will build a proper SAPUI5 user interface that consumes both the XSJS and XSODATA
services from our Node.js module.
Exercise Description
88
DAT375
EXERCISE 5 – SOLUTION
Explanation Screenshot
1. In Exercise 1 a simple
SAPUI5 Hello World
application was generated for
us by the module creation
wizard.
89
DAT375
- name: web
type: html5
path: web
requires:
- name: dat375-uaa
- name: dat375-ui5
- name: xsjs_api
group: destinations
properties:
name: xsjs_api
url: '~{url}'
forwardAuthToken: true
- name: js_api
group: destinations
properties:
name: js_api
url: '~{url}'
forwardAuthToken: true
90
DAT375
91
DAT375
Explanation Screenshot
data-sap-ui-
libs="sap.m,sap.ui.comp,sap.ui.core,sap.ui.layout"
data-sap-ui-frameOptions="trusted">
</script>
<script type="text/javascript" src="/common/error.js"
></script>
<script>
sap.ui.getCore().attachInit(function () {
var ComponentContainer =
new sap.ui.core.ComponentContainer({
height : "100%"
});
92
DAT375
new sap.m.Shell({
app: ComponentContainer,
showLogout: true
}).placeAt("content");
ComponentContainer.setComponent(oComponent);
});
});
</script>
</head>
errorRes.error.innererror.errordetail.DETAIL, {
93
DAT375
icon:
sap.m.MessageBox.Icon.ERROR,
title: "Service Call Error",
actions:
[sap.m.MessageBox.Action.OK],
styleClass:
"sapUiSizeCompact"
});
} else {
if (jqXHR.status === 500 || jqXHR.status ===
400) {
sap.m.MessageBox.show(jqXHR.responseText, {
icon:
sap.m.MessageBox.Icon.ERROR,
title: "Service Call Error",
actions:
[sap.m.MessageBox.Action.OK],
styleClass:
"sapUiSizeCompact"
});
return;
} else {
sap.m.MessageBox.show(jqXHR.statusText, {
icon:
sap.m.MessageBox.Icon.ERROR,
title: "Service Call Error",
actions:
[sap.m.MessageBox.Action.OK],
styleClass:
"sapUiSizeCompact"
});
return;
}
}
}
function oDataFailed(oControlEvent) {
sap.m.MessageBox.show("Bad Entity Definition", {
icon: sap.m.MessageBox.Icon.ERROR,
title: "OData Service Call Error",
actions: [sap.m.MessageBox.Action.OK],
styleClass: "sapUiSizeCompact"
});
return;
}
94
DAT375
destroy: function() {
// call the base component's destroy
function
UIComponent.prototype.destroy.apply(this,
arguments);
},
getSessionInfo: function() {
var aUrl =
"/xsjs/exercisesMaster.xsjs?cmd=getSessionInfo";
this.onLoadSession(
JSON.parse(jQuery.ajax({
url: aUrl,
method: "GET",
dataType: "json",
async: false
}).responseText));
},
onLoadSession: function(myJSON) {
for (var i = 0; i <
myJSON.session.length; i++) {
var config =
this.getModel("config");
config.setProperty("/UserName",
myJSON.session[i].UserName);
95
DAT375
}
}
});
});
96
DAT375
97
DAT375
<core:Fragment
fragmentName="teched.odataCreate.view.MRead"
type="XML"/>
</IconTabFilter>
</items>
</IconTabBar>
</u:content>
</u:Shell>
</core:View>
98
DAT375
99
DAT375
function fnLoadMetadata() {
oTable.setModel(oModel);
oTable.setEntitySet(mEntity1);
var oMeta =
oModel.getServiceMetadata();
var headerFields = "";
for (var i = 0; i <
oMeta.dataServices.schema[0].entityType[0].property.length;
i++) {
100
DAT375
var property =
oMeta.dataServices.schema[0].entityType[0].property[i];
headerFields +=
property.name + ",";
}
oTable.setInitiallyVisibleFields(headerFields);
}
oModel.attachMetadataLoaded(oModel, function() {
fnLoadMetadata();
});
oModel.attachMetadataFailed(oModel,
function() {
callCreate: function(oEvent) {
var oTable =
this.getView().byId("tblPOHeader");
var oModel = oTable.getModel();
// var result =
this.getView().getModel().getData();
var oEntry = {};
oEntry.PURCHASEORDERID =
"0000000000";
oEntry.PARTNERID = 100000000;
oEntry.CURRENCY = "EUR";
oEntry.GROSSAMOUNT = "1137.64";
oEntry.NETAMOUNT = "956.00";
oEntry.TAXAMOUNT = "181.64";
oEntry.DELIVERYDATE = new Date();
oEntry.APPROVALSTATUS = "I";
oEntry.CONFIRMSTATUS = "I";
oEntry["HISTORY.CHANGEDAT"] =
new Date();
oEntry["HISTORY.CHANGEDBY"] =
"1";
oEntry["HISTORY.CREATEDAT"] =
new Date();
101
DAT375
oEntry["HISTORY.CREATEDBY"] =
"1";
oEntry.INVOICINGSTATUS = "I";
oEntry.LIFECYCLESTATUS = "N";
oEntry.NOTEID = "9000000001";
oEntry.ORDERINGSTATUS = "I";
oModel.setHeaders({
"content-type":
"application/json;charset=utf-8"
});
var mParams = {};
mParams.success = function() {
sap.m.MessageToast.show("Create successful");
};
mParams.error = this.onErrorCall;
var mEntity1 =
this.getOwnerComponent().getModel().getProperty("/mEntity1"
);
oModel.create("/" + mEntity1, oEntry,
mParams);
},
onErrorCall: function(oError) {
if (oError.statusCode === 500 ||
oError.statusCode === 400 || oError.statusCode === "500" ||
oError.statusCode === "400") {
var errorRes =
JSON.parse(oError.responseText);
if (!errorRes.error.innererror) {
sap.m.MessageBox.alert(errorRes.error.message.valu
e);
} else {
if
(!errorRes.error.innererror.message) {
sap.m.MessageBox.alert(errorRes.error.innererror.toSt
ring());
} else {
sap.m.MessageBox.alert(errorRes.error.innererror.me
ssage);
}
}
return;
} else {
sap.m.MessageBox.alert(oError.response.statusText);
return;
}
102
DAT375
}
});
});
/**
* Convenience method for getting the
view model by name in every controller of the application.
* @public
* @param {string} sName the model
name
* @returns {sap.ui.model.Model} the
model instance
*/
getModel : function (sName) {
return
this.getView().getModel(sName);
},
/**
* Convenience method for setting the
view model in every controller of the application.
* @public
* @param {sap.ui.model.Model}
oModel the model instance
* @param {string} sName the model
name
* @returns {sap.ui.mvc.View} the view
instance
*/
103
DAT375
/**
* Convenience method for getting the
resource bundle.
* @public
* @returns
{sap.ui.model.resource.ResourceModel} the resourceModel of
the component
*/
getResourceBundle : function () {
return
this.getOwnerComponent().getModel("i18n").getResourceBun
dle();
},
/**
* Event handler for navigating back.
* It there is a history entry we go one
step back in the browser history
* If not, it will replace the current entry
of the browser history with the master route.
* @public
*/
onNavBack : function() {
var sPreviousHash =
History.getInstance().getPreviousHash();
if (sPreviousHash !==
undefined) {
history.go(-1);
} else {
});
}
);
104
DAT375
105
DAT375
106
DAT375
107
DAT375
Objective
Exercise Description
108
DAT375
EXERCISE 6 – SOLUTION
Explanation Screenshot
109
DAT375
110
DAT375
111
DAT375
www.sap.com/contactsap
112