2010-01-08 9 views
6

Wbijam sobie głowę w ścianę o to, co moim zdaniem byłoby bardzo prostym problemem do rozwiązania w Grails:Grails - sortowanie listy wyjściowej bez konieczności posiadania zestawu SortedSet lub porównywalnego modelu?

Załóżmy, że mam model podobny do koszyka; więc koszyk klasy, który ma wiele przedmiotów, a każdy przedmiot należy do koszyka. Ogólnie rzecz biorąc, nie obchodzi mnie kolejność przedmiotów w koszyku - nie obchodzi mnie, w jakiej kolejności są one przechowywane, przeliczone itp. JEDNAK, chcę wyświetlić je w tej samej kolejności. Wydaje mi się, że ta logika powinna istnieć CAŁKOWICIE w warstwie widoku, ale jedyne rozwiązania, jakie udało mi się znaleźć, każą mi zadeklarować elementy jako SortedSet w warstwie modelu. Wpływa to również na moją warstwę kontrolera, ponieważ proste operacje List, takie jak .collect {}, wymagają teraz dodatkowych skoków składniowych, aby zachować poprawność konwersji typów i zachować sortowanie.

Dla mnie to jest orzechy, więc brakuje mi czegoś prostego! Czy jest jakiś sposób, na przykład, na zrobienie czegoś takiego jak <g:each in="${cart.items.sort{it.name}}"> lub coś podobnego, tak, że mogę wymusić spójną kolejność wyświetlania TYLKO na warstwie wyjściowej/widoku? EDYCJA - Zobacz odpowiedź Matta poniżej; wersja tego faktycznie działa.

Dziękujemy za porady i wskazówki!

Odpowiedz

4

This 3rd party tag wygląda na to, że zrobi to, czego potrzebujesz. Jeśli nie, zawsze możesz stworzyć własny tag. Klasa Tag może zrobić sortowania jak ten

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

Ten znacznik może być następnie używane do sortowania kolekcji obiektów przez ich nazwa właściwości jak ten:

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

Kolekcja mowa o someCollection będzie posortowane w miejscu, gdy tag zostanie wykonany.

+0

To świetnie. W końcu natknąłem się na podobne rozwiązanie na tych samych liniach, używając interfejsu ProxyGenerator i komparatora, ale twój jest znacznie czystszy i zdecydowanie taki, jakiego szukałem. dzięki! – bprotas

22

Można również użyć metody sortowania dostępnych dla Kolekcje/Mapy zdefiniowane tutaj: http://groovy.codehaus.org/api/org/codehaus/groovy/runtime/DefaultGroovyMethods.html

Ja osobiście okazało się dość łatwe do zrobienia, to w połączeniu z <g:each/> tag w moim 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> 

Aby uzyskać więcej sposobów na manipulowanie kolekcjami i mapami, polecam odpowiednio this page i this page.

+0

Dzięki Matt ... Twoje rozwiązanie działa równie dobrze, a także jest bardzo czyste, chociaż mógłbym ZROBIĆ, że próbowałem tego wcześniej i to się nie udało ... mój mózg musiał być błotnisty. Dzięki! – bprotas

+0

Piękne! Kocham to! +1 – Eldelshell

+0

Dzięki Matt działa naprawdę dobrze – Vahid

Powiązane problemy