Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bind Aggregation Relative to Parent Selection

Tags:

sapui5

I have an XML view and a controller.

My model data is bound to the sap.m.Table. The problem is that I have to bind the "items" relative to a certain array element of my model.

These are my model data:

[{
  "type": "01",
  "items": [{
    "date": "20150720",
    "amount": 53.20,
    "paytype": "Cash"
  }, {
    "date": "20150720",
    "amount": 23.20,
    "paytype": "Cash"
  }]
}, {
  "type": "02",
  "items": [{
    "date": "20150720",
    "amount": 515.6,
    "paytype": "Credit Card"
  }, {
    "date": "20150720",
    "amount": 3,
    "paytype": "Something else"
  }]
}]

I want to bind my table to the "items" property according to a selection change of my Select control which has fields like "type" property bound.

How can I write the path of the items property of my table? "data>/items/" didn't work.

I thought about solution to bind the path value to an external model pathModel and to update its property according to a selection change of the select object like that:

My view:

<Table
  id="dataTable"
  items="{path>pathUrl}"
>

My controller:

newPath = "data>/"+ countPath +"/items/";
currentView.getModel("path").setProperty("/pathUrl", newPath);

But it's not working either.

like image 283
shmoolki Avatar asked Dec 11 '25 23:12

shmoolki


2 Answers

The question describes a typical use case for the concept Element Binding.

View

<Select
  forceSelection="false"
  change=".onSelectionChange"
  items="{myModel>/}"
>
  <core:Item
    key="{myModel>typeKey}"
    text="Type {myModel>type}"
  />
</Select>
<Table id="myTable" items="{myModel>items}">
  <items>
    <ColumnListItem>
      <Text text="{myModel>paytype}"/>
      <Text text="{myModel>amount}"/>
    </ColumnListItem>
  </items>
  <!-- ... -->
</Table>

Controller

onSelectionChange: function(event) {
  const selectedItem = event.getParameter("selectedItem");
  this.byId("myTable").bindElement({
    path: selectedItem.getBindingContext("myModel").getPath(), // e.g. "/1"
    model: "myModel",
  });
},

Once an item is selected from the Select control, the onSelectionChange is invoked with the selected item as a parameter. That item contains a binding context API which can be retrieved via .getBindingContext(/*modelName*/). Calling getPath() from it will return the absolute path of the bound data. In case of a JSONModel, the path will be index-like such as "/0", "/1", etc. In case of ODataModel; "/ProductSet('123')" for example.

The absolute binding path should be then assigned to the API bindElement.API All the relative binding paths within the element target, e.g. "{myModel>items}", can be then finally resolved showing the data to the UI.


Here is a working example using your data: https://embed.plnkr.co/FOEY1JZIKFAJTApe/.

enter image description here

like image 195
Boghyon Hoffmann Avatar answered Dec 14 '25 22:12

Boghyon Hoffmann


I have created a simple Plunker example that shows a simple way to achieve what you are looking for. Check it out here.

onSelectChange: function (ev) {
          var list = this.getView().byId("myList");
          var index = ev.getParameter("selectedItem").getKey();
          list.bindItems("/" + index + "/items",
            new sap.m.StandardListItem({
              title: "{amount}",
            description: "{paytype}"
            })
        );
        }

There is a sap.m.Select control with a change handler in which we bind the table to the proper items array.

like image 27
Deyan Yanakiev Avatar answered Dec 14 '25 22:12

Deyan Yanakiev