2014-05-22 4 views
10

Cela peut être une question de base, mais j'ai du mal à lier le compte Odata en mode XML. Dites, dans l'exemple suivant, je veux lier le nombre de produits à partir du modèle Odata.

<List items="{/Categories}"} > 
<ObjectListItem 
    title="{CategoryName}" 
    number="{path : 'Products/$count'}" 
    numberUnit="Products" 
</ObjectListItem> 
</List> 

Chaque catégorie doit afficher le nombre de produits dans la catégorie respective ..... comme dans

/Categories(1)/Products/$count 
/Categories(2)/Products/$count 

Merci pour votre aide à l'avance.

Répondre

7

Je ne pense pas que son actuellement possible - $ count est une option de requête OData, l'équivalent en ODataListBinding est longueur, par exemple Products.length je ne peux pas penser à un moyen de se lier à elle

vous pouvez obtenir le nombre dans quelques façons en utilisant un formatter

option 1 - la plus simple, créez une liste de liaison qui lit le nombre total de produits, il fait un appel synchrone et ne retourne que le nombre de $

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> 
Option

2 - utiliser une expansion et retourner un ensemble très restreint de données, la mise en garde dans ce cas seulement CategoryName et ProductID est de savoir si vous devez par la pagination de table passe pour obtenir la liste complète

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> 
3

bien .. J'avais exactement la même exigence et ne voulait pas exécuter la solution cleaver à partir de @jasper car il va charger toute la collection de produits du service oData.

Ce fut la façon dont je résous:

Voir

  1. Utilisez un régleur
  2. Donnez votre liste une carte d'identité
  3. Utilisez une fonction sur l'événement de la liste 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> 

Contrôleur

l'intérieur de votre contrôleur:

  1. Mettre en oeuvre "countProducts" fonction
  2. Utilisez jQuery pour demander le nombre de $ pour chaque élément de la liste - Remarquez comment l'URL est générée en concaténant l'URL du service du modèle avec le contenu de liaison de l'élément xt
  3. Comme jQuery utilise des requêtes asynchrones, au moment où vous obtenez la première réponse, vous serez probablement fini.Ainsi, il peut utiliser clojures pour éviter de remplir simplement le dernier élément de la liste avec votre réponse 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); 

    } 
+1

C'était la meilleure solution de loin, très appréciée! –

+0

Merci @ChrisR - Si possible, envisagez également d'ajouter une nouvelle propriété dans le service dorsal et d'implémenter le compte là aussi. Ensuite, vous bénéficierez d'une liaison simple en code UI5. – fabiopagoti

9

J'ai eu un problème similaire. Bien que je ne suis pas heureux avec ma solution, il utilise la liaison expression et fonctionne sans la nécessité d'un formatter séparé:

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

Comme @ Jasper_07, vous devez toujours inclure Products dans l'expansion, mais vous ignorez la plupart des les données reviennent.

+0

Cette réponse devrait être acceptée depuis l'introduction des liaisons d'expression. @c_y –

Questions connexes