2010-08-19 25 views
13

Bạn có biết cảm giác này khi mọi mã bạn viết hoạt động một cách im lặng và bạn đã vượt quá lịch biểu của mình :-P Nó giống như 'oh yeah, bây giờ tôi có thời gian để làm cho nó hoàn hảo'. Đó là nơi tôi đang ở thời điểm này ^^JSF2 Paging/Pager for Repeater

Vì vậy, tôi đã triển khai bộ lặp với JSF (ui: repeat) và tôi đã nghĩ về phân trang cho tất cả các thực thể. Có cách nào dễ dàng để làm điều đó không? Những điểm tôi phải suy nghĩ là gì?

Sẽ thật tuyệt nếu có ai đó giúp tôi. googleskills tôi đã không giúp tôi cho đến nay :-P

Cheers ...

+0

Bạn có sử dụng các richfaces trong ứng dụng của mình không? –

+0

Tôi thì không. Nhưng tôi có thể nếu điều đó giúp tôi :-) – Sven

Trả lời

21

Dưới đây là một ví dụ đơn giản mà nên cung cấp cho bạn những ý tưởng về làm thế nào để thực hiện điều này.

RepeatPaginator:

public class RepeatPaginator { 

    private static final int DEFAULT_RECORDS_NUMBER = 2; 
    private static final int DEFAULT_PAGE_INDEX = 1; 

    private int records; 
    private int recordsTotal; 
    private int pageIndex; 
    private int pages; 
    private List<?> origModel; 
    private List<?> model; 

    public RepeatPaginator(List<?> model) { 
     this.origModel = model; 
     this.records = DEFAULT_RECORDS_NUMBER; 
     this.pageIndex = DEFAULT_PAGE_INDEX;   
     this.recordsTotal = model.size(); 

     if (records > 0) { 
      pages = records <= 0 ? 1 : recordsTotal/records; 

      if (recordsTotal % records > 0) { 
       pages++; 
      } 

      if (pages == 0) { 
       pages = 1; 
      } 
     } else { 
      records = 1; 
      pages = 1; 
     } 

     updateModel(); 
    } 

    public void updateModel() { 
     int fromIndex = getFirst(); 
     int toIndex = getFirst() + records; 

     if(toIndex > this.recordsTotal) { 
      toIndex = this.recordsTotal; 
     } 

     this.model = origModel.subList(fromIndex, toIndex); 
    } 

    public void next() { 
     if(this.pageIndex < pages) { 
      this.pageIndex++; 
     } 

     updateModel(); 
    } 

    public void prev() { 
     if(this.pageIndex > 1) { 
      this.pageIndex--; 
     } 

     updateModel(); 
    } 

    public int getRecords() { 
     return records; 
    } 

    public int getRecordsTotal() { 
     return recordsTotal; 
    } 

    public int getPageIndex() { 
     return pageIndex; 
    } 

    public int getPages() { 
     return pages; 
    } 

    public int getFirst() { 
     return (pageIndex * records) - records; 
    } 

    public List<?> getModel() { 
     return model; 
    } 

    public void setPageIndex(int pageIndex) { 
     this.pageIndex = pageIndex; 
    } 

} 

Bean:

public class TestBean { 

    private List<String> list; 
    private RepeatPaginator paginator; 

    @PostConstruct 
    public void init() { 
     this.list = new ArrayList<String>(); 
     this.list.add("Item 1"); 
     this.list.add("Item 2"); 
     this.list.add("Item 3"); 
     this.list.add("Item 4"); 
     this.list.add("Item 5"); 
     this.list.add("Item 6"); 
     this.list.add("Item 7"); 
     this.list.add("Item 8"); 
     this.list.add("Item 9"); 
     this.list.add("Item 10"); 
     this.list.add("Item 11"); 
     paginator = new RepeatPaginator(this.list); 
    } 

    public RepeatPaginator getPaginator() { 
     return paginator; 
    } 

} 

XHTML:

<ui:composition xmlns="http://www.w3.org/1999/xhtml" 
    xmlns:ui="http://java.sun.com/jsf/facelets" 
    xmlns:f="http://java.sun.com/jsf/core" 
    xmlns:h="http://java.sun.com/jsf/html" 
    template="/WEB-INF/template/default.xhtml"> 

<ui:define name="content"> 
    <h:form> 
     <ui:repeat value="#{testBean.paginator.model}" var="listItem"> 
      <div> 
       <h:outputText value="#{listItem}"/> 
      </div> 
     </ui:repeat> 
     <h:commandButton value="&lt; prev" action="#{testBean.paginator.prev}"/> 
     <h:outputText value="#{testBean.paginator.pageIndex}/#{testBean.paginator.pages}"/> 
     <h:commandButton value="next &gt;" action="#{testBean.paginator.next}"/> 
     <h:inputHidden value="#{testBean.paginator.pageIndex}"/> 
    </h:form> 
</ui:define> 
</ui:composition> 
+1

Cảm ơn bạn cho rằng công cụ awsemoe :-) hoạt động hoàn hảo – Sven

+0

@mmanco bên trong UIRepeater là bạn có thể tạo các lệnh liên kết động không? –

9

Pagination là trong thực tế dễ dàng. Bạn chỉ cần tiếp tục truyền một hoặc hai tham số xung quanh: firstrow và tùy chọn rowcount (cũng có thể được giữ ở phía máy chủ). Khi người dùng cuối nhấp vào Tiếp theo, bạn chỉ cần tăng giá trị firstrow với giá trị là rowcount. Khi người dùng cuối nhấp vào Quay lại, bạn chỉ cần giảm giá trị của firstrow với giá trị là rowcount. Bạn chỉ cần kiểm tra xem nó có vượt quá biên giới của 0totalrows và thay đổi tương ứng hay không.

Sau đó, dựa trên mong muốn firstrowrowcount, bạn biết chính xác dữ liệu sẽ hiển thị. Nếu tất cả dữ liệu đã có trong một số List trong bộ nhớ của Java, thì bạn chỉ cần sử dụng List#subList() để lấy danh sách con từ nó để hiển thị. Tuy nhiên nó không hiệu quả để sao chép toàn bộ bảng cơ sở dữ liệu vào bộ nhớ của Java. Nó có thể không gây hại khi nó chỉ có 100 hàng, nhưng khi nó nhiều hơn thế và/hoặc bạn đang sao chép nó cho mỗi người dùng duy nhất, sau đó ứng dụng sẽ hết bộ nhớ rất sớm.

Trong trường hợp đó, bạn muốn phân trang ở cấp DB. Trong ví dụ MySQL bạn có thể sử dụng mệnh đề LIMIT để có được một tập con của các kết quả từ DB. JPA/Hibernate thậm chí còn cung cấp các cách sử dụng các phương thức setFirstResult()setMaxResults() tương ứng là QueryCriteria. Bạn có thể tìm thấy các ví dụ trong câu trả lời thisthis.

Bạn có thể tìm thấy ví dụ khởi động JSF 1.2 cơ bản được nhắm mục tiêu theo phân trang giống như Google (và sắp xếp) trong this article. Nó sử dụng các thành phần Tomahawk, nhưng trong JSF 2.0 bạn chỉ có thể để chúng đi bằng cách làm cho bean @ViewScoped (thay thế t:saveState) và sử dụng ui:repeat (thay thế t:dataList).

Cuối cùng nhưng không kém phần quan trọng, có rất nhiều thư viện thành phần thực hiện tất cả các công việc trong một thành phần. Ví dụ: RichFaces<rich:datascroller>PrimeFaces<p:dataTable paginator="true"> (cũng có thể được thực hiện ajaxical).

+0

Hm, tôi thực sự ngạc nhiên, rằng bạn không bao gồm một ví dụ điển hình 'BalusC-kickoff'. :) Tuy nhiên, tôi vẫn thích cách tiếp cận DB. – alexander

+0

@BalusC: Xin chào BalusC, có vẻ như các nguyên tố giới thiệu ui: lặp lại phân trang sau khi kiểm tra liên kết này [http://blog.primefaces.org/?p=1808](http://blog.primefaces.org/?p= 1808) nhưng liên kết bên trong bài viết này không hợp lệ, bạn có thể làm rõ chúng tôi điểm này không? Có giải pháp phần tử cho ui: phân trang lặp lại không? –

+0

@Jad: đó là ' '. – BalusC