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

Спасибо за вашу помощь заранее.

3 ответов


Я не думаю, что в настоящее время можно - $count-это опция запроса OData, эквивалент в ODataListBinding-длина, например, продукты.длина я не могу придумать способ привязаться к нему

вы можете достичь подсчета несколькими способами, используя форматер

Вариант 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>

у меня была аналогичная проблема. Хотя я не в восторге от моего решения, он использует привязку выражений и работает без необходимости отдельного форматирования:

<List items="{/Categories}"} >  
<ObjectListItem 
   title="{CategoryName}"
   number="{= ${Products}.length}"
   numberUnit="Products" 
</ObjectListItem>
</List>

Как @Jasper_07, вам все равно нужно включить Products в разверните, но вы игнорируете большую часть возвращаемых данных.


хорошо.. У меня было ровно то же самое требование и не хотел выполнять умное решение от @jasper, поскольку он загрузит всю коллекцию продуктов из службы oData.

вот как я это решаю:

посмотреть

  1. использовать контроллер
  2. дайте вашему списку ID
  3. используйте функцию в списке updateFinished событие.
<mvc:View 
  controllerName="view.Root"
  xmlns:mvc="sap.ui.core.mvc"
  xmlns="sap.m"
>
  <List id="list"
    headerText="Categories"
    items="{/Categories}"
    growing="true"
    growingThreshold="4"
    growingScrollToLoad="true"
    updateFinished=".countProducts"
  >
    <ObjectListItem
      title="{description}"
      numberUnit="Products"
    />
  </List>
</mvc:View>

контроллер

  1. реализовать countProducts функции
  2. используйте jQuery для запроса $count для каждого элемента списка-обратите внимание, как создается URL-адрес службы модели конкатенации с контекстом привязки элемента
  3. поскольку jQuery использует асинхронные запросы, к моменту получения первого ответа ваш for будет закончен. Так что он может использовать жизнь чтобы избежать заполнения только последнего элемента списка AJAX response
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);
  }
}