2010-08-19 11 views
13

Conoscete questa sensazione quando ogni codice che scrivete funziona in modo impeccabile e sottovalutate il vostro programma :-P È come 'oh sì, ora ho il tempo di renderlo perfetto'. Ecco dove sono al momento ^^JSF2 Cercapersone/Cercapersone per Repeater

Così ho implementato un ripetitore con JSF (ui: repeat) e ho pensato a un paging per tutte le entità. C'è forse un modo semplice per farlo? Quali sono i punti a cui devo pensare?

Sarebbe bello se qualcuno mi dà un aiuto. I miei googleskills non mi hanno aiutato finora :-P

Cin cin ...

+0

Usi le interfacce nell'applicazione? –

+0

Io no. Ma potrei se ciò mi aiuta :-) – Sven

risposta

21

Ecco un semplice esempio che dovrebbe dare l'idea su come implementare questa.

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

Grazie per quella roba da awsemoe :-) funziona perfettamente – Sven

+0

@mmanco all'interno dell'UIRepeater sei capace di creare dinamicamente commandLinks? –

9

impaginazione è infatti facile. Devi solo passare uno o due parametri in giro: firstrow e facoltativamente rowcount (che può anche essere tenuto sul lato server). Quando l'utente finale fa clic su Avanti, è sufficiente incrementare il valore di firstrow con il valore di rowcount. Quando l'utente finale fa clic su Indietro, si diminuisce il valore di firstrow con il valore di rowcount. Hai solo bisogno di controllare se non supera i confini di 0 e totalrows e modificare di conseguenza.

Quindi, in base allo firstrow e rowcount desiderato, è possibile conoscere esattamente quali dati visualizzare. Se tutti i dati sono già presenti in alcuni List nella memoria Java, è sufficiente utilizzare List#subList() per ottenere una sottolista da esso per la visualizzazione. Tuttavia, non è efficiente duplicare l'intera tabella del database nella memoria di Java. Non può danneggiare quando è solo 100 righe, ma quando è molto più di questo e/o lo si duplica per ogni singolo utente, l'applicazione esaurirà la memoria molto presto.

In questo caso preferisci impaginare a livello di DB. Ad esempio, per MySQL è possibile utilizzare la clausola LIMIT per ottenere un sottoinsieme di risultati dal DB. JPA/Hibernate fornisce anche modi utilizzando i metodi setFirstResult() e setMaxResults() di Query e Criteria rispettivamente. È possibile trovare esempi nella risposta this e this.

È possibile trovare un esempio di kickoff di base JSF 1.2 mirato di paginazione (e ordinamento) simile a Google in this article. Utilizza i componenti Tomahawk, ma in JSF 2.0 puoi semplicemente lasciarli fuori facendo il bean @ViewScoped (sostituisce t:saveState) e usando ui:repeat (sostituisce t:dataList).

Ultimo ma non meno importante, ci sono molte librerie di componenti che fanno tutto il lavoro in un singolo componente. Ad esempio RichFaces<rich:datascroller> e PrimeFaces<p:dataTable paginator="true"> (può anche essere fatto ajaxical).

+0

Hm, sono davvero sorpreso che tu non abbia incluso un esempio tipico di "BalusC-kickoff". :) Comunque, mi piace l'approccio DB comunque. – alexander

+0

@BalusC: Salve BalusC, sembra che primefaces introduce ui: ripeti l'impaginazione dopo aver controllato questo link [http://blog.primefaces.org/?p=1808](http://blog.primefaces.org/?p= 1808) ma il link all'interno di questo articolo non è valido, per favore puoi chiarirci questo punto? Esiste una soluzione primefaces per ui: ripetere l'impaginazione? –

+0

@Jad: è il ''. – BalusC