SAP UI5: Declaring the Model and OData Service in manifest.json and Using Model Data in XML View
In my previous posts on SAPUI5, I often used somewhat "creepy" methods for declaring the model and OData services in demo applications. In this post, I’d like to go over alternative — and, let’s say, more proper — ways of working with these components.
Example 1
Declaring the OData Service in manifest.json
(1)
To declare the OData service used by the application, make the necessary changes in manifest.json
.
See also:
Descriptor (manifest.json)
Descriptor for Applications, Components, and Libraries
For example:
"dataSources": {
"backend": {
"uri": "/sap/opu/odata/sap/ZREACT_APP_SRV/",
"type": "OData",
"settings": {
"odataVersion": "2.0"
}
}
}
Declaring the Model in manifest.json
(2)
In addition to the initialized OData service above, a newly created SAP UI5 application will also need a data model. This model can also be declared in manifest.json
.
See also
Models
Example:
employee": {
"dataSource": "backend",
"type": "sap.ui.model.odata.v2.ODataModel"
}
N.B. Pay attention to the type of the declared model (type
attribute).
See also:
Class class sap.ui.model.odata.v2.ODataModel
The resulting manifest.json
with the relevant changes will look like this:
Using manifest.json
to Populate View with Data (3)
Once the OData service and corresponding data model are declared, you need to update the View in your SAPUI5 app to display the data returned by the service.
<mvc:View controllerName="com_zapplication99.controller.Table" xmlns:html="http://www.w3.org/1999/xhtml" xmlns:mvc="sap.ui.core.mvc"
displayBlock="true" xmlns="sap.m">
<App>
<pages>
<Page>
<content>
<Table id="idEmployeesTable" inset="false" fixedLayout="Strict" alternateRowColors="true" items="{path: \'employee>/employeeSet\'}">
<headerToolbar>
<OverflowToolbar>
<Title text="{i18n>title}" level="H2"/>
</OverflowToolbar>
</headerToolbar>
<columns>
<Column >
<Text text="Personnel Number"/>
</Column>
<Column >
<Text text="Name of Employee"/>
</Column>
<Column minScreenWidth="Tablet">
<Text text="EMail"/>
</Column>
</columns>
<items>
<ColumnListItem>
<cells>
<ObjectIdentifier text="{employee>id}"/>
<Text text="{employee>name}"/>
<Text text="{employee>email}"/>
</cells>
</ColumnListItem>
</items>
</Table>
</content>
</Page>
</pages>
</App>
</mvc:View>
Please note that the View specifies the model and corresponding entitySet, allowing data to be fetched for the control. A key feature of this approach is that the model is bound directly to the control. As a result, the framework independently handles the call to the OData service and the specified entitySet
to retrieve and display the data.
Testing the Output
Declaring the OData Service in manifest.json
(1)
To try an alternative approach, I’ll register a new data source, which in this case will be a locally created JSON file.
Shown here in the project structure:
Declaring the Model in manifest.json
(2)
I define the data model in manifest.json
.
N.B. Pay attention to the type of the declared model (type
attribute).
See also:
Class class sap.ui.model.json.JSONModel
Retrieving Data for the View (3)
In this example, it’s not enough to rely solely on manifest.json
settings — we’ll need to handle some logic in the controller.
Example:
var oModel = this.getOwnerComponent().getModel("employee");
var oModel2 = this.getOwnerComponent().getModel("localJSON");
oModel.read("/employeeSet", {
success: function(oData, response) {
oModel2.setProperty("/employeeData", oData.results);
}
}
See also:
Controller
Class class sap.ui.model.json.JSONModel (setProperty)
Then I update the View:
<mvc:View controllerName="com_zapplication99.controller.Table" xmlns:html="http://www.w3.org/1999/xhtml" xmlns:mvc="sap.ui.core.mvc"
displayBlock="true" xmlns="sap.m">
<App>
<pages>
<Page>
<content>
<Table id="idEmployeesTable" inset="false" fixedLayout="Strict" alternateRowColors="true" items="{path: \'localJSON>/employeeData\'}">
<headerToolbar>
<OverflowToolbar>
<Title text="{i18n>title}" level="H2"/>
</OverflowToolbar>
</headerToolbar>
<columns>
<Column >
<Text text="Personnel Number"/>
</Column>
<Column >
<Text text="Name of Employee"/>
</Column>
<Column minScreenWidth="Tablet">
<Text text="EMail"/>
</Column>
</columns>
<items>
<ColumnListItem>
<cells>
<ObjectIdentifier text="{localJSON>id}"/>
<Text text="{localJSON>name}"/>
<Text text="{localJSON>email}"/>
</cells>
</ColumnListItem>
</items>
</Table>
</content>
</Page>
</pages>
</App>
</mvc:View>
Testing the Output
Compared to the approach in Example #1, this method provides more flexibility for the developer/consultant to manipulate the data in the model before binding it to application controls.
See also:
Class class sap.ui.model.json.JSONModel (setProperty)
A Small Adjustment to the Controller Code
onAfterRendering: function() {
var oModel = this.getOwnerComponent().getModel("employee");
var oModel2 = this.getOwnerComponent().getModel("localJSON");
oModel.read("/employeeSet", {
success: function(oData, response) {
oModel2.setProperty("/employeeData", oData.results);
oModel2.setProperty("/myProperty", "signatov.com");
}
}
);
}
Adding New Property Output in the View
<mvc:View controllerName="com_zapplication99.controller.Table" xmlns:html="http://www.w3.org/1999/xhtml" xmlns:mvc="sap.ui.core.mvc"
displayBlock="true" xmlns="sap.m">
<App>
<pages>
<Page>
<content>
<Table id="idEmployeesTable" inset="false" fixedLayout="Strict" alternateRowColors="true" items="{path: \'localJSON>/employeeData\'}">
<headerToolbar>
<OverflowToolbar>
<Title text="{i18n>title}" level="H2"/>
<Title text="with love from {localJSON>/myProperty}" level="H2"/>
</OverflowToolbar>
</headerToolbar>
<columns>
<Column >
<Text text="Personnel Number"/>
</Column>
<Column >
<Text text="Name of Employee"/>
</Column>
<Column minScreenWidth="Tablet">
<Text text="EMail"/>
</Column>
</columns>
<items>
<ColumnListItem>
<cells>
<ObjectIdentifier text="{localJSON>id}"/>
<Text text="{localJSON>name}"/>
<Text text="{localJSON>email}"/>
</cells>
</ColumnListItem>
</items>
</Table>
</content>
</Page>
</pages>
</App>
</mvc:View>
Checking the Output
P.S.
Special thanks to my colleague Mikhail for assistance and advice on some of the technical aspects.