2010-01-08 4 views
6

Je me heurte la tête contre le mur à propos de ce que je pense que serait un problème très simple à résoudre dans Grails:Grails - Sort la liste de sortie sans avoir à avoir un SortedSet ou un modèle Comparable?

Dites que j'ai un modèle de shopping-cart-like; donc un panier de classe qui a de nombreux articles, et chaque article appartient au panier. En général, je ne me soucie pas de l'ordre des articles dans le panier - peu importe l'ordre dans lequel ils sont stockés, calculés, etc. Cependant, je veux les afficher dans le même ordre. Il me semble que cette logique devrait pouvoir exister ENTIEREMENT dans la couche de vue, mais les seules solutions que j'ai pu trouver me disent de déclarer des éléments comme SortedSet dans la couche modèle. Cela affecte également ma couche de contrôleur, car de simples opérations List telles que .collect {} nécessitent désormais un saut syntaxique supplémentaire pour que les conversions de type restent correctes et préservent mon tri.

Pour moi, c'est fou, il me manque quelque chose de simple! Est-il possible, par exemple, de faire quelque chose comme <g:each in="${cart.items.sort{it.name}}"> ou quelque chose de similaire, de sorte que je puisse appliquer un ordre d'affichage cohérent UNIQUEMENT à la couche de sortie/vue? EDIT - Voir la réponse de Matt ci-dessous; une version de cela fonctionne réellement.

Nous vous remercions de vos conseils ou de vos conseils!

Répondre

4

This 3rd party tag semble vouloir faire ce dont vous avez besoin. Sinon, vous pouvez toujours créer votre propre tag. La classe Tag pourrait faire le tri comme celui-ci

class SortTagLib { 

    static namespace = 'sort' 

    def sort = { attrs -> 

     // A closure that does the sorting can be passed as an attribute to the tag. 
     // If it is not provided the default sort order is used instead 
     def sorter = attrs.sorter ?: {item1, item2 -> item1 <=> item2} 
     sorter = sorter as Comparator   

     // The collection to be sorted should be passed into the tag as a parameter 
     Collections.sort(attrs.items, sorter) 
    } 
} 

Cette balise pourrait alors être utilisée pour trier une collection d'objets par leur propriété de nom comme celui-ci:

<sort:sort items="someCollection" sorter="${someComparatorClosure}"/> 

La collection appelée par someCollection sera trié sur place lorsque la balise est exécutée.

+0

C'est génial. Je suis finalement tombé sur une solution similaire dans le même sens en utilisant un ProxyGenerator et l'interface Comparator, mais le vôtre est beaucoup plus propre, et certainement le genre de solution que je recherchais. Merci! – bprotas

22

Vous pouvez également utiliser les méthodes de tri disponibles pour les collections/Maps comme défini ici: http://groovy.codehaus.org/api/org/codehaus/groovy/runtime/DefaultGroovyMethods.html

J'ai personnellement trouvé assez facile de le faire en conjonction avec une étiquette <g:each/> dans mon GSP:

<!-- Books sorted by title --> 
<g:each in="${ books.sort{a,b-> a.title.compareTo(b.title)} }"> 
    <p>Title: ${it.title}</p> 
    <p>Author: ${it.author}</p> 
</g:each> 

Pour plus de façons de manipuler Collections et Maps, je recommande respectivement this page et this page.

+0

Merci Matt ... Votre solution fonctionne aussi, et elle est aussi très propre, bien que je puisse dire que j'ai essayé ça plus tôt et qu'elle a échoué ... mon cerveau devait être boueux. Merci! – bprotas

+0

Magnifique! Aime ça! +1 – Eldelshell

+0

Merci Matt travaille vraiment bien – Vahid

Questions connexes