2013-01-07 7 views
5

Ich versuche herauszufinden, wie man echte Paginierung mit richfaces datascroller tun kann.Richfaces 3 wie man datascroller echte Paginierung macht

Derzeit zieht meine Abfrage alle Daten aus einer Tabelle und ich will es so, wenn Sie auf die nächste Schaltfläche des Datascroller klicken, wird es die Datenbank für die nächsten 20 Zeilen abfragen.

Ich verstehe, wie Sie die Abfrage schreiben, um die Zeilen zu begrenzen, aber ich bin mir nicht sicher, wie man die nächste Schaltfläche des datascroller ruft, um eine bestimmte Methode aufzurufen.

Ich sehe, es gibt viele Leute, die auf den Richfaces-Foren mit möglichen Lösungen veröffentlichen, aber sie alle verwenden ein DataModel. Da ich kein ORM verwende, bin ich nicht sicher, wie ich diese Lösungen zu dem, was ich habe, passen kann.

Jede Hilfe wird geschätzt.

<rich:extendedDataTable id="resultsTable" value="#{tableBacking.results}" var="results" sortMode="single" rowKeyVar="row"> 
    <rich:columns value="#{tableBacking.columns == null ? '' : tableBacking.columns}" var="columns" index="ind" id="column#{ind}" sortBy="#{results[ind].data}" rendered="#{tableBacking.columns != null}"> 
     <f:facet name="header"> 
      <h:outputText value="#{columns.columnDescription}" /> 
     </f:facet> 

     <h:outputText value="#{results[ind].data}" /> 

    </rich:columns> 

</rich:extendedDataTable> 

<rich:datascroller for="resultsTable" page="#{tableBacking.page}" renderIfSinglePage="false" /> 

bean Backing

public class TableBacking { 
    private List<List<TableData>> results = null; 
    private int page = 0; 

    public int getPage() { 
    return page; 
    } 
    public void setPage(int page) { 
    this.page = page; 
    } 
    public List<List<TableData>> getResults() throws Exception { 
    return results; 
    } 
    public void setResults(List<List<TableData>> results) { 
    this.results = results; 
    } 

    private void getData(String whereClause) { 

    try { 
    DataDao dd = new DataDao(); 
    results = dd.getData(); // dd.getData just runs a query on a table and puts the results in a List of lists. 
    } catch (Exception e) {} 
} 

Antwort

0

Sie benötigen rich:extendedDataTable auf ein Attribut in Ihrem Backing Bean zu binden.

Java

private HtmlExtendedDataTable Table; 
//Getter and setter 

Danach Sie die Ansicht

xhtml

<rich:extendedDataTable id="resultsTable" value="#{tableBacking.results}" var="results" sortMode="single" rowKeyVar="row" binding="#{tableBacking.Table}">

Richfaces HtmlExtendedDataTable hat eine Methode binden zu überprüfen, wie viele Zeilen pro Seite angezeigt werden , genannt getRows(). Wenn bohnen initialisiert wird, laden Sie einfach die ersten Seitenwerte (Sie können nur die IDs der Elemente auf den Rest der Seiten laden und später, wenn Sie auf die Seite zugreifen, laden Sie sie basierend auf der ID).

<rich:datascroller/> auch ein Ereignis, das ausgelöst wird, wenn eine Seite Schaltfläche geklickt wird, und Sie können auf diese Weise, dass von Ihrem Backing Bean erwerben:

xhtml

<f:facet name="footer"> 
<rich:datascroller id="ds" 
       scrollerListener="#{tableBacking.actionOnPageChange}" /> 
</f:facet> 

Java

public String actionOnPageChange(DataScrollerEvent event)

Diese DataScrollerEvent enthält, welche Seite vom Benutzer angeklickt wurde, die Sie mit getNewScrolVal() erhalten können. Wenn das passiert, lade einfach die Werte der entsprechenden Seite in deine Tabelle und das war's.

+0

Das Problem, das ich mit dieser Lösung habe, ist, dass die datascroller Rendering nicht, weil ich meine Datatable Zeilen 20 und beim Laden der Seite werden nur 20 Zeilen angezeigt. Weißt du, wie du das umgehen kannst? Gibt es eine Möglichkeit, dem Datascroller die maximale Anzahl von Zeilen mitzuteilen, damit er weiß, wie viele Seiten berechnet werden müssen? – Catfish

+0

Ich bin mir nicht sicher, ob ich verstehe, was Sie mit "' Sie können nur die IDs der Elemente auf den Rest der Seiten laden und später, wenn Sie auf die Seite zugreifen, laden sie basierend auf der ID " – Catfish

+0

Sie hat gesagt, dass Sie kein ORM verwenden. Ich habe diese Lösung mit Hibernate verwendet, indem ich die ganzen Daten, aber einige Attribute beim Lazy Loading geladen habe. Wenn ich eine Seite anfordere, kann ich diese Objekte laden und Lazy Load Ausnahmen verhindern. In Ihrem Fall denke ich, dass Sie * unechte * Objekte (denen nur das ID-Attribut zugewiesen sein muss) auf nicht sichtbaren Seiten speichern können. Wie erreiche ich das? Die gesamte ID-Liste von Anfang an laden und die relativen Informationen nur dann mitnehmen, wenn sie benötigt werden. Ich weiß nicht, wie dein Modell funktioniert, ich gebe nur eine Idee. –

2

versuchen, dies zu tun:

JSF-Bestellung:

<rich:dataTable id="listTable" var="record" rows="10" value="#{personBean.data}"> 
    .... 
    <f:facet name="footer"> 
     <rich:column colspan="8"> 
     <rich:dataScroller page="#{personBean.page}" for="listTable" 
       scrollListener="#{personBean.scrollPage}" render="listTable" /> 
     </rich:column> 
     Records : #{personBean.data.size()} 
    </f:facet> 
</rich:dataTable> 

Java BackBean Stuff:

public class PersonBean { 
    // List of Persons 
    private PagedList<Person> data; 

    // Current page 
    private Integer page; 

    // Default rows to display 
    private Integer rows = 10; 

    // Persistence layer 
    private DaoService daoService; 

    @PostConstruct 
    public void init(){ 
     page= 1; 
    } 

    // Event trigger on scroll page 
    public void scrollPage(DataScrollEvent ev) { 
     log.debug("Scroll event"); 
     reset(); 

     // getPersons execute 2 queries : the first query is the count(*) and the result is set in TotalElements 
     // the second query gets the 'n' records defined in rows , something like this : 
     // select * from Persons LIMIT page*rows, (page*rows) + rows and the result is set in Content 
     Page<Person> pageResult = this.daoService.getPersons(filter, page - 1, rows); 

     // Now create a pagedList with the constructor 
     this.data = new PagedList<Person>(pageResult.getContent(), (int) pageResult.getTotalElements(), this.pageSize); 
    } 
} 

Java PagedList

public final class PagedList<E> extends AbstractList<E> { 

    private final List<E> lista; 
    private final int total; 
    private final int pageSize; 

    public PagedList(List<E> lista, int total, int pageSize) { 
     this.lista = lista; 
     this.total = total; 
     this.pageSize = pageSize; 
    } 

    public int size() { 
     return total; 
    } 

    public E get(int i) { 
     i = i % this.pageSize; 
     return lista.get(i); 
    } 
} 

Der Trick ist, das gesamte Eigentum der PagedList Klasse mit der Zählung der dataTable in der Datenbank zu setzen und nur die ausgelagerten Elemente in der Liste der PageList gesetzt.

Sorry für mein schlechtes Englisch: P

0

Die beste Lösung, die ich gefunden habe, ist die Abbildung des „value“ Attribut des Datatable zu einer org.richfaces.model.ExtendedTableDataModelproperty. Anschließend initialisieren Sie das ExtendedTableDataModel mit einer Instanz von org.richfaces.model.DataProvider. Beispiel:

Nach Ansicht:

<rich:dataTable id="table" value="#{bean.model}" rows="#{bean.rows}"> 
    <!-- columns --> 
    <f:facet name="footer"> 
     <rich:dataScroller for="table"/> 
    </f:facet> 
</rich:dataTable> 

In der Bohne:

@ManagedBean 
public class Bean { 
    private int rows = 15; // the ammount of rows per page. 
    private org.richfaces.model.ExtendedTableDataModel model = new org.richfaces.model.ExtendedTableDataModel(
     new org.richfaces.model.DataProvider(
     public int getRowCount() { 
      // count your rows. 
     } 

     public List<T> getItemsByRange(int first, int quantity) { 
      // fetch the page's rows. 
     } 

     public T getItemByKey(Object o) { 
      return null; // no need to implement this. 
     } 

     public Object getKey(T t) { 
      return null; // no need to implement this. 
     ) 
    ); 

    public int getRows() { return rows; } 
    public ExtendedTableDataModel getModel() { return model; } 

} 
Verwandte Themen