2010-08-19 5 views
13

Kennen Sie dieses Gefühl, wenn jeder Code, den Sie schreiben, sofort funktioniert und Sie Ihren Zeitplan unterlaufen :-P Es ist wie 'oh yeah jetzt habe ich Zeit es perfekt zu machen'. Dort bin ich im Moment ^^JSF2 Paging/Pager für Repeater

Also habe ich einen Repeater mit JSF (UI: Repeat) implementiert und ich dachte über ein Paging für alle Entitäten nach. Gibt es vielleicht einen einfachen Weg das zu tun? Über welche Punkte muss ich nachdenken?

Wäre nett, wenn mir jemand Hilfe gibt. Meine googleskills haben mir geholfen, nicht so weit :-P

Prost ...

+0

Verwenden Sie Richfaces in Ihrer Anwendung? –

+0

Ich nicht. Aber ich könnte, wenn das mir hilft :-) – Sven

Antwort

21

Hier ist ein einfaches Beispiel, das Sie auf die Idee, wie dies zu implementieren geben sollte.

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

Danke für das awsemoe Zeug :-) funktioniert perfekt – Sven

+0

@mmanco innerhalb der UIRepeater sind Sie in der Lage, dynamisch Befehls-Links zu erstellen? –

9

Paginierung ist in der Tat einfach. Sie müssen lediglich einen oder zwei Parameter übergeben: firstrow und optional rowcount (die auch auf der Serverseite gespeichert werden können). Wenn der Endbenutzer auf Next klickt, erhöhen Sie einfach den Wert firstrow mit dem Wert rowcount. Wenn der Endbenutzer auf Zurück klickt, dekrementieren Sie einfach den Wert firstrow mit dem Wert rowcount. Sie müssen nur prüfen, ob die Grenzen von 0 und totalrows nicht überschritten werden, und entsprechend ändern.

Dann, basierend auf den gewünschten firstrow und rowcount, wissen Sie genau, welche Daten angezeigt werden. Wenn alle Daten bereits in einigen List im Java-Speicher sind, dann verwenden Sie einfach List#subList(), um eine Unterliste von ihm zur Anzeige zu erhalten. Es ist jedoch nicht effizient, die gesamte Datenbanktabelle in den Speicher von Java zu duplizieren. Es kann nicht schaden, wenn es nur 100 Zeilen sind, aber wenn es viel mehr ist und/oder du es für jeden einzelnen Benutzer duplizierst, dann wird der Anwendung sehr bald der Speicher ausgehen.

In diesem Fall möchten Sie lieber auf DB-Ebene paginieren. In MySQL können Sie beispielsweise die LIMIT-Klausel verwenden, um eine Teilmenge der Ergebnisse aus der DB zu erhalten. JPA/Hibernate bietet sogar Möglichkeiten, setFirstResult() und setMaxResults() Methoden von Query bzw. Criteria zu verwenden. Sie finden Beispiele in this und this Antwort.

Sie können ein grundlegendes Kickoff-Beispiel für Google-ähnliche Paginierung (und Sortierung) in JSF 1.2 in this article finden. Es verwendet Tomahawk-Komponenten, aber in JSF 2.0 können Sie sie einfach weglassen, indem Sie die Bean @ViewScoped (ersetzt t:saveState) und ui:repeat (ersetzt t:dataList) verwenden.

Last but not least, gibt es viele Komponentenbibliotheken, die alle Arbeiten in einer einzigen Komponente erledigen. Zum Beispiel RichFaces<rich:datascroller> und PrimeFaces<p:dataTable paginator="true"> (kann auch ajaxical getan werden).

+0

Hm, ich bin wirklich überrascht, dass du kein typisches 'BalusC-Kickoff'-Beispiel mitgenommen hast. :) Trotzdem mag ich den DB-Ansatz trotzdem. – alexander

+0

@BalusC: Hallo BalusC, es scheint, dass primefaces führt ui: wiederhole Paginierung nach Überprüfung dieses Links [http://blog.primefaces.org/?p=1808](http://blog.primefaces.org/?p= 1808) aber der Link in diesem Artikel ist nicht gültig, bitte können Sie uns diesen Punkt verdeutlichen? Gibt es eine Standardlösung für ui: Paginierung wiederholen? –

+0

@Jad: es ist die ''. – BalusC