Dear SAPUI5 guru's,
Let's start by saying I'm an ABAP developer who's exploring SAPUI5, so I'm still a rookie at the time of writing. I challenged myself by developing a simple UI5 app that shows information about my colleagues like name, a pic, address data and their skills. The app uses the sap.m library and most of the views are XML based which I prefer.
The data is stored on an ABAP system and exposed via a gateway service. This service has 2 entities: Employee and Skill. Each employee can have 0..n skills and association/navigation between these 2 entities is set up correctly in the service. The data of this service is fetched from within the app using a sap.ui.model.odata.ODataModel model.
The app uses the splitApp control which shows the list of employees on the left side (master view). If a user taps an employee, the corresponding details of the employee entity are shown on the right (detail view).
Up till here everything is fine but I've been struggling with my latest requirement which is: show the skills of the selected employee in a separate XML view when the user performs an action (for the time being, I just created a button on the detail view to perform the action). After some hours I actually got it working but I doubt if my solution is the right way to go. And that's why I'm asking for your opinion here.
Let's explain how I got things working. First of all I created a new XML view called 'Skills'. The content on this view is currently just a Table with 2 columns:
<core:View xmlns:core="sap.ui.core" xmlns:mvc="sap.ui.core.mvc" xmlns="sap.m" controllerName="com.pyramid.Skills" xmlns:html="http://www.w3.org/1999/xhtml"> <Page title="Skills" showNavButton="true" navButtonPress="handleNavButtonPress"> <content> <Table id="skillsTable"> <columns> <Column> <Label text="Name"/> </Column> <Column> <Label text="Rating"/> </Column> </columns> </Table> </content> </Page></core:View>
The button on the Detail view calls function showSkills:
showSkills: function(evt) { var context = evt.getSource().getBindingContext(); this.nav.to("Skills", context); var skillsController = this.nav.getView().app.getPage("Skills").getController(); skillsController.updateTableBinding(); },
Within 'this.nav.to("Skills", context);' I add the Skills view to the splitApp and set its bindingContext to the current binding context (e.g. "EmployeeSet('000001')"). Then I call function updateTableBinding in the controller of the Skills view which dynamically binds the items in the table based on the selected employee. So, when the ID of the selected employee is '000001', the path of the table's item binding should be "/EmployeeSet('000001')/Skills"
updateTableBinding: function(){ var oTemplate = new sap.m.ColumnListItem( {cells: [ new sap.m.Text({text : "{Name}"}), new sap.m.Text({text : "{Rating}"}) ] }); var oView = this.getView(); var oTable = oView.byId("skillsTable"); var oContext = oView.getBindingContext(); var path = oContext.sPath + "/Skills"; oTable.bindItems(path, oTemplate); },
Allthough it works fine, this is where I have my first doubt. Is this the correct way to bind the items? I tried to change the context that is passed to this.nav.to and wanted it to 'drill-down' one level, from Employee to Skills, but I couldn't manage to do that.
I also tried to bind using the items aggregation of the table within the XML declaration (<Table id="skillsTable" items="{/EmployeeSet('000001')/Skills}">). This works fine if I hard-code the employee ID but off course this ID needs to be dynamic.
Any better suggestions?
The second doubt is about the template parameter passed to the bindItems method. This template is declared in the controller via javascript. But I'm using XML views! So why should I declare any content in javascript?? I tried to declare the template in the XML view itself by adding an items tag with a ColumnListItem that has an ID:
<items> <ColumnListItem id="defaultItem"> <cells> <Text text="{Name}"/> </cells> <cells> <Text text="{Rating}"/> </cells> </ColumnListItem> </items>
Then, in the updateTableBinding function, I fetched this control (by ID), and passed it as the template parameter to the bindItems method. In this case the table shows a few lines but they don't contain any data and their height is only like 1 mm! Does anyone know where this strange behaviour comes from or what I'm doing wrong?
I hope I explained my doubts clearly enough. If not, let me know which additional info is required.
Looking forward to your opinions/suggestions,
Rudy Clement.