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);

    }