I am trying to bind items in a sap.m.Table (preventing usage of a Factory function) and I am getting this error:
Missing template or factory function for aggregation items of Element
My views looks as follows:
<Table id="favTable">
<headerToolbar>
<Toolbar>
<Title id="tableHeader" text="{i18n>tableHeader}"/>
</Toolbar>
</headerToolbar>
<columns>
<Column>
<Label text="{i18n>serviceNameColText}" />
</Column>
<Column>
<Label text="{i18n>serviceTechNameColText}"/>
</Column>
<Column width="50px"/>
</columns>
<ColumnListItem>
<Text text="{Text}" />
<Text text="{Service}" />
<Button icon="sap-icon://delete" press="onDeleteRow" />
</ColumnListItem>
</Table>
According controller code (using a bound OData service) tries to bind items into the view after the route has been hit:
_onPatternMatched: function(oEvent) {
let oTable = this.getView().byId(sIdTable);
// bind items dynamically with attributes
const sGroupId = oEvent.getParameter("arguments").Group;
let sBindingPath = "/DataSet(SetId='" + sSetId + "')"
oTable.bindItems({
path: sBindingPath,
parameters: {
navigation: {
FavoriteGroupSet: "ToFavorites"
}
},
filters: [
// new Filter("InstitutionId", "EQ", oEvent.getParameter("arguments").Institution),
new Filter("SetId", "EQ", sSetId)
]
})
},
What do I need to do to make the correct binding to show up the correct data?
In UI5's concept of aggregation binding, you can use two mechanisms to build the aggregation items:
I would assume that you want to use the ColumnListItem
from your XML as a template. The problem is that when building XML views, controls are used as templates for the parent aggregation only when you also bind the parent aggregation in XML as well. Otherwise, they are interpreted as simple children.
In a nutshell, UI5 interprets your view as if you have a sap.m.Table
with a single, static item. When you try to bind the items
aggregation later, it destroys this item (well, actually it just throws an error in your case, as you must specify either a template or a factory when you use the bindAggregation method (bindItems
is just a wrapper for this method).
One option to correct this would be to use relative binding and then use the bindElement method instead to change the Table's binding. In your case, it is not really clear what you want to do, as the sBindingPath
seems to have a value like /DataSet(SetId='ABC')
, which actually will not point towards a collection, but towards a single DataSet entity.
If you actually change the way in which your OData service is used and you have a navigation (e.g. the path would look something like /DataSet('ABC')/MyNavigationSet
), then you can do the following:
View:
<!-- note that the items binding path should not start with / (to be relative) -->
<Table id="favTable" items={MyNavigationSet}>
<columns>
<!-- your columns... -->
</columns>
<items>
<ColumnListItem id="favTableItemTemplate">
<cells>
<Text text="{Text}" />
<Text text="{Service}" />
<Button icon="sap-icon://delete" press="onDeleteRow" />
</cells>
</ColumnListItem>
</items>
</Table>
Controller:
function(oEvent) {
// the rest of your code
this.byId("favTable").bindElement(sBindingPath);
}
Another option which works with your current OData service is to declare your template as a dependent and then use it for the binding. The templateShareable
flag should be set such that the template is not destroyed on re-binding the aggregation.
View:
<Table id="favTable">
<columns>
<!-- your columns... -->
</columns>
<dependents>
<ColumnListItem id="favTableItemTemplate">
<cells>
<Text text="{Text}" />
<Text text="{Service}" />
<Button icon="sap-icon://delete" press="onDeleteRow" />
</cells>
</ColumnListItem>
</dependents>
</Table>
Controller:
function(oEvent) {
// the rest of your code
this.byId("favTable").bindItems({
path: sBindingPath,
template: this.byId("favTableItemTemplate"),
templateShareable: true,
parameters: {
navigation: {FavoriteGroupSet: "ToFavorites"}
},
filters: [new Filter("SetId", "EQ", sSetId)]
})
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With