Warm tip: This article is reproduced from serverfault.com, please click

SAPUI5 sap.m.list in a popover is emtpy when populated using bindElement

发布于 2020-11-30 20:30:34

I have a table (sap.m.table) with different columns. One columns contains a link and when the user clicks on the link a popover fragment opens and shows some details in a list (sap.m.list). The data is coming from an oData Service. One Entity feeds the table and through a navigation property the data for the popover is fetched.

I have a working example for this scenario where I create the the list template in the controller. But I believe that this should also be possible just by xml and a bindElement in the controller. What is the mistake in my second scenario?

First Scenario (which is working fine): Popover XML:

    <Popover
    showHeader="false"
    contentWidth="320px"
    contentHeight="300px"
    placement="Bottom"
    ariaLabelledBy="master-title">
        <Page
            id="master"
            class="sapUiResponsivePadding--header"
            title="Aktionen">
            <List
                id="AktionList">                    
            </List>
        </Page>
</Popover>

Calling the Popover in the controller file (sPath is /TableEntity('123456')/AktionSet):

if (!this._oPopover) {
Fragment.load({
    id: "popoverNavCon",
    name: "bernmobil.ZPM_STOERUNG_FDA.view.AktionPopover",
    controller: this
}).then(function(oPopover){
    this._oPopover = oPopover;
    this.getView().addDependent(this._oPopover);
    
    var oList = Fragment.byId("popoverNavCon", "AktionList");
    var oItemTemplate = this._BuildItemTemplate();
    oList.bindAggregation("items", sPath, oItemTemplate);
    this._oPopover.openBy(oControl);
  }.bind(this));
} else {
    var oList = Fragment.byId("popoverNavCon", "AktionList");
    var oItemTemplate = this._BuildItemTemplate();
        oList.bindAggregation("items", sPath, oItemTemplate);
    this._oPopover.openBy(oControl);
}
_BuildItemTemplate: function(){
        var oItemTemplate = new sap.m.ObjectListItem({
            title:"{AktionsBez}", 
            type: "Inactive"              
        });
        
        oItemTemplate.addAttribute(new sap.m.ObjectAttribute({
            text : "{Aktionstext}"
        }));
        oItemTemplate.addAttribute(new sap.m.ObjectAttribute({
            text : "{path: 'ChangedAt', type: 'sap.ui.model.type.DateTime'}"
        }));
        return oItemTemplate;       
    }

And this is the idea of the second scenario which is calling the oDataService but not displaying any data: Instead of having only the List definition in XML also the ObjectListItem is defined in the XML:

<List
    id="AktionList"
    items="{AktionSet}"> 
    <ObjectListItem 
        title="{AktionsBez}"
        type="Active">
        <ObjectAttribute text="{Aktionstext}" />
        <ObjectAttribute text="{ChangedAt}" />
    </ObjectListItem>
</List>

And in the controller instead of building the template and doing the bindAggretation there is just:

var oList = Fragment.byId("popoverNavCon", "AktionList");
oList.bindElement(sPath);

How do I get the second scenario displaying data in the list?

Questioner
Cruncher
Viewed
0
Marc 2020-12-01 20:03:07

I would suggest a third solution:

When pressing on your table row, get the binding context of the current row using oContext = oClickedRow.getBindingContext() or something similar. This context should point to /TableEntity('123456').

Apply this context to your Popover using oPopover.setBindingContext(oContext).

Now your Popover has the same context as your table row. The XML should look like in your second scenario.

Using the path is an extra step imo. I think it also makes more sense to bind the complete Popover and not just the List. Has the neat side effect that you can use a property of your TableEntity as the title for the Popover. It also completely avoids working with controls directly (which is one of the seven deadly sins) and you should be able to remove all those IDs.