What is use of 'parameters' option in binding object? - sapui5

In the code below, what is the significance of parameters option and select option within it?
I have looked into API but to avail nothing.
<List id="list"
items="{
path: '/PurchaseOrders',
sorter: [{
path: 'ChangedAt',
descending: true
}, {
path: 'POId',
descending: false
}],
parameters: {
select: 'POId,OrderedByName,SupplierName,GrossAmount,CurrencyCode,ChangedAt,ItemCount'
}
}">
...
</List>

With the select property you can tell the server to return just a subset of entity properties. This is useful if you have large entities with a lot of properties, but want to display only some of them, e.g. in a table. This works only if you are using an ODataModel and thus an ODataListBinding.
In general the parameters argument is used to pass implementation specific parameters to the binding while having a common API for all model implementations, i.e. all implementations of a ListBinding have the following signature:
oModel (the model which holds the data)
sPath (the binding path)
oContext (the binding context)
aSorters (sorters to be applied)
aFilters (filters to be applied)
mParameters (additional parameters which depend on the model implementation and are not necessarily supported by all of them)

Related

Rows binding in sap.ui.table.Table dynamically

I have made a title depending on variable how it's shown in: Title depending on other variable in SAPUI5
I would like to make the same with rows in sap.ui.table.Table so I tried:
rows="{= ${someData>/infos}.length > 0 ? ${someData>/infos} : ${someData>/result}}"
Whereas someData is an ODataModel (v2).
But got an error:
Uncaught TypeError: Cannot read property 'indexOf' of undefined
Problem
The problem is that you're trying to determine .length from an object. In ODataListBinding (someData>/infos), aggregations are resolved in an object rather than an array. Therefore the syntax can't work. Furthermore, the .length syntax implies that the whole collection is already available on the client-side, contradicting the purpose of sap.ui.table.Table.
Expression binding with .length makes only sense with a client-side JSONModel as mentioned here.
Alternative approach
There are multiple ways to define aggregation binding dynamically, but the most straight-forward solution would be just to access the table control reference and call bindRows dynamically. Something like this:
onInit: function() {
this.loadCountOf("SomeSet", this.bindTableRows.bind(this));
// ...
},
loadCountOf: function(entitySetName, handleCountSuccess) {
const odataModel = /*...*/;
odataModel.read(`/${entitySetName}/$count`, {
success: count => handleCountSuccess.call(this, +count),
});
},
bindTableRows: function(count) {
this.byId("myTable").bindRows({
path: count > 0 ? "/SomeSet" : "/TheOtherSet",
// ...
});
},
API reference: sap.ui.table.Table#bindRows
the errors seem to tell you that either infos or result is undefined. You should check the current value of those arrays.
Anyway, it's not a really good idea to bind table rows like that IMHO.
What's you scenario?

API reference: Where to find all the properties available for aggregation binding info object?

Where can I find aggregation binding properties like path, factory, etc.. in the API reference?
Just like in following code
<List items="{
path: '/Products',
factory: '.productListFactory',
...
}">
Where to find more such properties and their descriptions?
You can see more such properties in ManagedObject#bindAggregation.
Additionally, parameters and events await key-value pairs of which the possible keys are documented in the corresponding model type.
For example, the keys for parameters, when binding with a v2.ODataModel, can be found in ODataModel#bindList or in ODataListBinding. The latter module also documents which events can be registered.
{ // Standard options. See ManagedObject bindAggregation
path: '...',
filters: [/*...*/],
...
parameters: { // Model dependent. See e.g. ODataListBinding constructor
expand: 'ToA, ToB/ToB1/ToB2, ToC',
select: 'ProductID, ProductName',
custom: 'myCustomQuery',
batchGroupId: 'myGroup',
},
events: { // Model dependent. See e.g. ODataListBinding events
dataRequested: '.onDataRequested',
dataRequested: '.onDataReceived',
change: '.onDataChange'
}
}
That's a binding (they're enclosed in {}).
You can use the getBindingInfo method.
So, for example, if your List control has the id "mylist":
this.getView().byId("mylist").getBindingInfo("items");
It will return you an object containing all the binding properties, such as path and factory.

Filter expanded OData request

I need to pass a parameter to the backend. I want to use $filter for this.
My code below is not working, there are no filters returned by io_tech_request_context->get_filter( )->get_filter_select_options( ) in the Figures entityset.
var aFilters = [ new sap.ui.model.Filter("TeamMembers/Figures/FILTERKEY", sap.ui.model.FilterOperator.EQ, sFilterValue) ];
this.getView().bindElement({
path: "/TeamDataSet('0')",
parameters: {
expand: 'TeamMembers/Figures'
},
filters: aFilters
});
Element binding / ContextBinding doesn't support the property filters since you're binding just a single entity and not a collection. If you need to filter Figures, you'll have to bind them to an aggregation (e.g. items on List), get the corresponding ListBinding object, and then call .filter from there.
Here is a similar example: https://embed.plnkr.co/AoIZI4/. Take a look at the handler onSearch.
In case someone actually wants to filter a list by expanded results, the navigation property can be applied in the Filter path which then gets resolved by the path of the bound binding object. For example:
<List items="{
path: 'myODataModel>/Products',
parameters: {
expand: 'ToSupplier'
}
}">
Then in Controller, filter Products by their supplier country:
new Filter({
path: "ToSupplier/Country",
operator: "EQ",
value1: "UK",
})
(From: https://embed.plnkr.co/wAlrHB/).
Be aware that this works only if expanding does not result in a collection but a single object (e.g. associated supplier). Filtering by looking up at an associated collection is supported as of OData V4 which can be achieved via FilterOperator.All / .Any.

NavigationListItem & Sort

I tried to sort a NavigationListItem on a field which is different from the keyfield within the onInit method of the view controller w/o any success.
Note, there is no orderby implementation on the server side.
My xml view which doesn't implement any sorter since orderby isn't implemented: https://openui5.hana.ondemand.com/#/api/sap.tnt.NavigationListItem
<tnt:NavigationList id="navigationList">
<tnt:NavigationListItem icon="sap-icon://"
expanded="{expanded}"
key="{MY_KEY}"
items="{/MY_PATH}">
<tnt:NavigationListItem text="{MY_CONTENT}" key="{MY_KEY}"></tnt:NavigationListItem>
</tnt:NavigationListItem>
</tnt:NavigationList>
Here is an attempt to add a sorter that presently doesn't work. First, because return items correspond to the first level of NavigationListItem and secondly probably because of a wrong approach.
var oNavigationList = this.getView().byId('navigationList');
var aSorter = [];
aSorter[0] = new sap.ui.model.Sorter('MY_FIELD', true);
var oItems = oNavigationList.getItems();
oItems.sort("items", {path: "/MY_PATH", sorter: aSorter});
Could you please advice on the appropriate approach?
Since your List is bound to ODATA Model, all the sorting will happen at server side. Every time you say, sort, a new request is sent to server. Now, as you said, the server is not supporting orderby, I suggest the following approach :
Do oDataModel.read and store the data in a JSON Model. oData Read API
Apply the sorting in XML using below code:
<tnt:NavigationList id="navigationList">
<tnt:NavigationListItem icon="sap-icon://"
expanded="{expanded}" key="{MY_KEY}"
items="{
path : '/MY_PATH',
sorter: {
path: 'MY_CONTENT',
descending: false,
group: false
},
}">
<tnt:NavigationListItem text="{MY_CONTENT}"
key="{MY_KEY}"></tnt:NavigationListItem>
</tnt:NavigationListItem>
</tnt:NavigationList>
Let me know if you need more information.

Number of items limited to around 100

I've created the following Input field.
var oCityInput = new Input({ // sap/m/Input
showSuggestion: true,
showTableSuggestionValueHelp: true,
suggestionItems:{
path: "/cities",
template: new ListItem({ // sap/ui/core/ListItem
text: "{cname}",
additionalText: "{provi}"
}),
},
});
The "cities" array contains around 8400 record, but when I type some character the suggestion function it seems that is looking for only in the first 100 items of the array.
I've created an example in jsbin. If you try to looking for the first elements it works... but if you try to type the last city the suggestion will not come out.
In newer versions of SAP UI5 the JSONModel also supports the setSizeLimit() method:
model.setSizeLimit(iNumOfYourJsonEntries);
API description: "Set the maximum number of entries which are used for list bindings."
Be careful because it can lead to performance issues.