2012-08-13 13 views
6

Ich weiß, es gibt eine ganze Reihe von Stellen JSF paginatin in Bezug auf hier, aber keiner von ihnen satisfed mich.JSF, Richfaces, Paginieren

Um ziemlich große Daten in Seiten aufgeteilt I Richfaces Daten scroller Komponente verwenden werden.

Es schien dafür geeignet zu sein, aber es sieht aus wie es funktioniert „künstliche“ Paginierung.

Was i ist hier nicht gefällt, dass es alle Daten geladen und zeigt dann nur einen Teil davon. Zumindest scheint es so zu sein. Korrigiere mich, wenn ich falsch liege.

Reiche Gesichter haben schöne Demos, aber aus irgendeinem Grund sie überspringen Bohne Definitionen sich nur xhtml. Ich habe eine Erwähnung von ExtendedDataModel gesehen, aber das einzige Beispiel, das ich gefunden habe, hat mich nicht beeindruckt. Warum soll ich 5 Bildschirm-Code haben nur zeigen Teilmenge von Daten?

Ehrlich gesagt eine so einfache Frage wie Paginierung geschah sehr komplex in JSF sein, und ich wirklich nicht bekommen, warum.

Also meine Fragen sind: 1. ist es möglich, in Richfaces nur einer Seite von Daten zu laden 2. ohne es zu Sitzung zu speichern (ich meine nicht aktuelle Daten state aktuelle Seite auflisten, usw.)

ich bin interessiert nur in Richfaces lib wie es bereits in meinem Projekt verwenden und nicht, was die Abhängigkeit von somethin sonst

Danke im Voraus

+0

Dies ist eine interessante Frage, die das RichFaces-Team selbst beantworten muss. Es wäre gut, es im [RichFaces Developer Forum] (https://community.jboss.org/en/richfaces/dev?view=discussions) zu veröffentlichen. Wenn Sie dort eine zufriedenstellende Antwort erhalten, posten Sie sie hier und markieren Sie sie als Antwort. –

Antwort

4

nach einem Gespräch über Richfaces Forum kam zur Einführung dieses folgende Lösung (thanx zu Brendan Healey):

RichLazyDataModel.java

/** 
* Extended data model 
* @author Brendan Healey 
*/ 
public abstract class RichLazyDataModel<T> extends ExtendedDataModel<T> { 

private SequenceRange cachedRange; 
private Integer cachedRowCount; 
private List<T> cachedList; 
private Object rowKey; 

public abstract List<T> getDataList(int firstRow, int numRows); 
public abstract Object getKey(T t); 
public abstract int getTotalCount(); 

@Override 
public void walk(FacesContext ctx, DataVisitor dv, Range range, Object argument) { 

    SequenceRange sr = (SequenceRange) range; 

    if (cachedList == null || !equalRanges(cachedRange, sr)) { 
     cachedList = getDataList(sr.getFirstRow(), sr.getRows()); 
     cachedRange = sr; 
    } 

    for (T t : cachedList) { 
     if (getKey(t) == null) { 
      /* 
      * the 2nd param is used to build the client id of the table 
      * row, i.e. mytable:234:inputname, so don't let it be null. 
      */ 
      throw new IllegalStateException("found null key"); 
     } 
     dv.process(ctx, getKey(t), argument); 
    } 

} 


/* 
* The rowKey is the id from getKey, presumably obtained from 
* dv.process(...). 
*/ 
@Override 
public void setRowKey(Object rowKey) { 
    this.rowKey = rowKey; 
} 

@Override 
public Object getRowKey() { 
    return rowKey; 
} 

@Override 
public boolean isRowAvailable() { 
    return (getRowData() != null); 
} 

@Override 
public int getRowCount() { 
    if (cachedRowCount == null) { 
     cachedRowCount = getTotalCount(); 
    } 
    return cachedRowCount; 
} 

@Override 
public T getRowData() { 
    for (T t : cachedList) { 
     if (getKey(t).equals(this.getRowKey())) { 
      return t; 
     } 
    } 
    return null; 
} 

protected static boolean equalRanges(SequenceRange range1, SequenceRange range2) { 
    if (range1 == null || range2 == null) { 
     return range1 == null && range2 == null; 
    } else { 
     return range1.getFirstRow() == range2.getFirstRow() && range1.getRows() == range2.getRows(); 
    } 
} 



/* 
* get/setRowIndex are used when doing multiple select in an 
* extendedDataTable, apparently. Not tested. Actually, the get method is 
* used when using iterationStatusVar="it" & #{it.index}. 
*/ 
@Override 
public int getRowIndex() { 
    if (cachedList != null) { 
     ListIterator<T> it = cachedList.listIterator(); 
     while (it.hasNext()) { 
      T t = it.next(); 
      if (getKey(t).equals(this.getRowKey())) { 
       return it.previousIndex() + cachedRange.getFirstRow(); 
      } 
     } 
    } 
    return -1; 
} 

@Override 
public void setRowIndex(int rowIndex) { 
    int upperBound = cachedRange.getFirstRow() + cachedRange.getRows(); 
    if (rowIndex >= cachedRange.getFirstRow() && rowIndex < upperBound) { 
     int index = rowIndex % cachedRange.getRows(); 
     T t = cachedList.get(index); 
     setRowKey(getKey(t)); 
    } 
} 

@Override 
public Object getWrappedData() { 
    throw new UnsupportedOperationException("Not supported yet."); 
} 

@Override 
public void setWrappedData(Object data) { 
    throw new UnsupportedOperationException("Not supported yet."); 

} 

public List<T> getCachedList() { 
    return cachedList; 
} 

}

ListState.java

/** 
* Holds list state 
*/ 
public class ListState implements Serializable { 

private int page; 

private Map<String, Serializable> searchCriteria = new HashMap<String, Serializable>(); 

public int getPage() { 
    return page; 
} 

public void setPage(int page) { 
    this.page = page; 
} 

public Map<String,Serializable> getSearchCriteria() { 
    return searchCriteria; 
} 

}

CardsBean.java

@ManagedBean(name="cardsBean") 
public class CardsBean { 

@ManagedProperty("#{cardService}") 
private CardService cardService; 

private ListState state; 

private RichLazyDataModel<Card> cardsModel = new RichLazyDataModel<Card>() { 
    @Override 
    public List<Card> getDataList(int firstRow, int numRows) { 
     MyUserDetails user = SecurityUtils.getCurrentUser(); 
     return cardService.findUserCards(user.getUser(), firstRow, numRows, state.getSearchCriteria()); 
    } 

    @Override 
    public Object getKey(Card card) { 
     return card.getId(); 
    } 

    @Override 
    public int getTotalCount() { 
     MyUserDetails user = SecurityUtils.getCurrentUser(); 
     return cardService.countUserCards(user.getUser(), state.getSearchCriteria()); 
    } 
}; 


public RichLazyDataModel<Card> getCards() { 
    return cardsModel; 
} 

public String getSearchString() { 
    return (String)state.getSearchCriteria().get("searchString"); 
} 

public int getCurrentPage() { 
    return state.getPage(); 
} 

public void setCurrentPage(int page) { 
    state.setPage(page); 
} 

public void setSearchString(String searchString) { 
    state.getSearchCriteria().put("searchString", searchString); 
} 

public void setCardService(CardService cardService) { 
    this.cardService = cardService; 
} 

public boolean isPinned() { 
    return Boolean.TRUE.equals(state.getSearchCriteria().get("pinned")); 
} 

public void setPinned(boolean pinned) { 
    state.getSearchCriteria().put("pinned", pinned); 
} 

public void togglePinned() { 
    setPinned(!isPinned()); 
} 

@PostConstruct 
public void init() { 
    state = getFromSession("cardsList", null); 
    if (state == null) { 
     state = new ListState(); 
     storeInSession("cardsList", state); 
    } 
} 

public <T extends Serializable> T getFromSession(String name, T defaultValue) { 
    T ret = (T) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get(name); 
    if (ret == null) { 
     ret = defaultValue; 
    } 
    return ret; 
} 

public void storeInSession(String name, Serializable obj) { 
    FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put(name, obj); 
} 
} 

cards.xhtml (teilweise)

... 

<h:form> 

    <rich:dataGrid value="#{cardsBean.cards}" var="card" columns="2" elements="20" first="#{cardsBean.currentPage}" style="margin:0 auto;width:70em" id="cardsTable"> 
     <f:facet name="header"> 
      <h:inputText value="#{cardsBean.searchString}"> 
       <a4j:ajax event="keyup" render="[email protected], [email protected]"> 
       <a4j:attachQueue requestDelay="700" ignoreDupResponses="true" /> 
       </a4j:ajax> 

      </h:inputText> 
     </f:facet> 

     <rich:panel id="cd"> 
      <ui:include src="WEB-INF/parts/card.xhtml"> 
       <ui:param name="card" value="#{card}"/> 
      </ui:include> 


     </rich:panel> 

     <f:facet name="footer"> 
      <rich:dataScroller page="#{cardsBean.currentPage}" /> 
     </f:facet> 

    </rich:dataGrid> 

    </h:form> 
... 
+0

Kannst du nicht auf deine Diskussion im Forum verweisen? Vielen Dank. –

+0

https://developer.jboss.org/thread/204005?tstart=0 Das ursprüngliche Thema gefunden. – Century

Verwandte Themen