2010-01-08 7 views
6

Tôi đập đầu lên tường về những gì tôi nghĩ sẽ là một vấn đề rất đơn giản để giải quyết trong Grails:Grails - Sắp xếp danh sách đầu ra mà không cần phải có một mô hình SortedSet hoặc Comparable?

Giả sử tôi có mô hình mua sắm giống như giỏ hàng; do đó, một Giỏ hàng có nhiều mục và mỗi mục thuộc về giỏ hàng. Nói chung, tôi không quan tâm đến thứ tự của các mặt hàng trong giỏ hàng - Tôi không quan tâm thứ tự chúng được lưu trữ, được tính toán, v.v. THẾ NÀO, tôi muốn HIỂN THỊ chúng theo cùng một thứ tự. Dường như với tôi rằng logic này sẽ có thể tồn tại ENTIRELY trong lớp xem, nhưng các giải pháp duy nhất tôi đã có thể tìm thấy cho tôi biết để khai báo các mục như một SortedSet trong lớp mô hình. Điều này cũng ảnh hưởng đến lớp điều khiển của tôi, vì các thao tác Danh sách đơn giản như .collect {} giờ yêu cầu thêm cú pháp nhảy xung quanh để giữ cho kiểu chuyển đổi đúng và duy trì việc sắp xếp của tôi.

Với tôi, đây là loại hạt, vì vậy tôi phải thiếu một cái gì đó đơn giản! Có cách nào, ví dụ, để làm một cái gì đó như <g:each in="${cart.items.sort{it.name}}"> hoặc một cái gì đó tương tự, để tôi có thể thực thi một lệnh hiển thị nhất quán ONLY ở đầu ra/xem lớp? EDIT - Xem câu trả lời của Matt dưới đây; một phiên bản này thực sự hoạt động.

Cảm ơn bạn đã đưa ra lời khuyên hoặc gợi ý!

Trả lời

4

This 3rd party tag có vẻ như nó sẽ làm những gì bạn cần. Nếu không, bạn luôn có thể tạo thẻ của riêng mình. Lớp Tag có thể làm như sắp xếp như thế này

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

Thẻ này sau đó có thể được sử dụng để sắp xếp một bộ sưu tập của các đối tượng bằng cách sở hữu tên của họ như thế này:

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

Bộ sưu tập gọi bằng someCollection sẽ được sắp xếp tại chỗ khi thẻ được thực thi.

+0

Điều đó thật tuyệt. Cuối cùng tôi đã vấp phải một giải pháp tương tự dọc theo các dòng tương tự bằng cách sử dụng một ProxyGenerator và giao diện Comparator, nhưng của bạn là sạch hơn nhiều, và chắc chắn là loại giải pháp mà tôi đang tìm kiếm. cảm ơn! – bprotas

22

Bạn cũng có thể sử dụng các phương pháp phân loại có sẵn cho bộ sưu tập/Maps như đã định nghĩa ở đây: http://groovy.codehaus.org/api/org/codehaus/groovy/runtime/DefaultGroovyMethods.html

Cá nhân tôi đã tìm thấy nó khá dễ dàng để làm được điều này kết hợp với một thẻ <g:each/> trong GSP của tôi:

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

Để biết thêm các cách bạn có thể thao tác Bộ sưu tập và Bản đồ, tôi khuyên bạn nên this pagethis page tương ứng.

+0

Cảm ơn Matt ... Giải pháp của bạn hoạt động tốt, và cũng rất sạch sẽ, mặc dù tôi có thể SWEAR mà tôi đã thử điều này trước đó và nó không thành công ... bộ não của tôi phải có bùn lầy. Cảm ơn! – bprotas

+0

Đẹp! Thích cái này! +1 – Eldelshell

+0

Cảm ơn Matt hoạt động rất tốt – Vahid