SAPUI5 - Как привязать счет Odata $к представлению XML
Может быть, это основной вопрос, но мне сложно связать счет Odata в представлении XML.
Скажем, в следующем примере я хочу связать количество продуктов с моделью Odata.
<List items="{/Categories}"} >
<ObjectListItem
title="{CategoryName}"
number="{path : 'Products/$count'}"
numberUnit="Products"
</ObjectListItem>
</List>
Каждая категория должна отображать количество товаров в соответствующей категории..... как в
/Categories(1)/Products/$count
/Categories(2)/Products/$count
Спасибо за вашу помощь заранее.
Ответы
Ответ 1
Я не думаю, что в настоящее время это возможно
- $count - опция запроса OData, эквивалент в ODataListBinding - длина, например Products.length. Я не могу придумать способ привязки к ней.
вы можете достигнуть счета несколькими способами, используя форматтер
вариант 1 - самый простой, создать привязку списка, которая считывает общее количество продуктов, выполняет синхронный вызов и возвращает только число $count
function productCount(oValue) {
//return the number of products linked to Category // sync call only to get $count
if (oValue) {
var sPath = this.getBindingContext().getPath() + '/Products';
var oBindings = this.getModel().bindList(sPath);
return oBindings.getLength();
}
};
<List items="{/Categories}"} >
<ObjectListItem
title="{CategoryName}"
number="{path : 'CategoryName',formatter:'productCount'}"
numberUnit="Products"
</ObjectListItem>
</List>
вариант 2 - используйте разворот и верните очень маленький набор данных, в данном случае только CategoryName и ProductID, оговорка здесь заключается в том, нужно ли вам переводить пейджинг таблицы, чтобы получить полный список
function productCount(oValue) {
//read the number of products returned
if (oValue) {
return oValue.length;
}
};
<List items="{/Categories,parameters:{expand:'Products', select:'CategoryName,Products/ProductID'}}">
<ObjectListItem
title="{CategoryName}"
number="{path : 'Products',formatter:'productCount'}"
numberUnit="Products"
</ObjectListItem>
</List>
Ответ 2
У меня была аналогичная проблема. Хотя я не в восторге от своего решения, он использует привязку выражения и работает без необходимости отдельного форматирования:
<List items="{/Categories}"} >
<ObjectListItem
title="{CategoryName}"
number="{= ${Products}.length}"
numberUnit="Products"
</ObjectListItem>
</List>
Как и @Jasper_07, вам все равно нужно включить Products
в раскрывающийся список, но вы игнорируете большую часть возвращаемых данных.
Ответ 3
Ну.. У меня было ровно одно и то же требование, и я не хотел выполнять решение cleaver от @jasper, так как он будет загружать всю коллекцию продуктов из службы oData.
Так я решил это:
Просмотр
- Использовать контроллер
- Дайте вашему списку идентификатор
- Используйте функцию в списке updateFinished.
<core:View
controllerName="view.Root"
xmlns:core="sap.ui.core"
xmlns:mvc="sap.ui.core.mvc"
xmlns="sap.m">
<List
id="list"
headerText="Categories"
items="{/Categories}"
growing="true"
growingThreshold="4"
growingScrollToLoad="true"
updateFinished="countProducts">
<items>
<ObjectListItem
title="{description}"
numberUnit="Products">
</ObjectListItem>
</items>
</List>
</core:View>
контроллер
Внутри вашего контроллера:
- Внедрить функцию countProducts
- Используйте jQuery для запроса счетчика $для каждого элемента списка. Обратите внимание, как создается URL-адрес, объединяющий URL-адрес службы модели с контекстом привязки элемента.
- Поскольку jQuery использует асинхронные запросы, к тому времени, когда вы получите первый ответ, вероятно, ваш будет завершен. Таким образом, он может использовать clojures, чтобы не заполнить только последний элемент списка с ответом ajax.
countProducts: function(e){
var m = sap.ui.getCore().getModel();
var items = this.byId("list").getItems();
for (var item_index=0; item_index<items.length; item_index++) {
var item = items[item_index];
(function(_item){
$.get(
m.sServiceUrl +
_item.getBindingContextPath() +
"/Categorias/$count",
function(count){
_item.setNumber(count);
});
})(item);
}