2012-08-13 19 views
6

Wiem, że istnieje sporo postów dotyczących stronicowania JSF tutaj, ale żadna z nich mnie nie satysfakcjonuje.JSF, RichFaces, paginacja

Do dzielenia dużych danych na strony miałem zamiar użyć komponentu rolki danych RichFaces.

Wyglądało na to, że nadaje się do tego, ale wygląda na to, że robi "sztuczną" paginację.

Tu nie podoba mi się to, że ładuje wszystkie dane, a następnie wyświetla tylko jego część. Przynajmniej wydaje się, że to robi. Popraw mnie, jeśli się mylę.

Bogate twarze mają ładne dema, ale z jakiegoś powodu pomijają definicje fasoli - tylko xhtml. Widziałem niektóre wzmianki o ExtendedDataModel, ale jedynym przykładem znalazłem nie zaimponowało mi. Dlaczego mam ustawiony na 5 kodów ekran po prostu wyświetlić podzbiór danych?

Szczerze mówiąc, tak proste pytanie jak paginacja okazało się bardzo złożone w JSF i nie wiem dlaczego.

Więc moje pytania to: 1. Czy jest możliwe w Richfaces załadować tylko jedną stronę danych 2. bez zapisywania go do sesji (mam na myśli rzeczywiste dane nie wymienione państwa- strony aktualny itp)

Jestem zainteresowany tylko w Richfaces lib jak już używać go w moim projekcie, a nie co do wprowadzenia zależność Czegoś innego

thanx z góry

+0

To interesujące pytanie, ale musi mu udzielić odpowiedni zespół RichFaces. Dobrze byłoby opublikować go na [RichFaces Developer Forum] (https://community.jboss.org/en/richfaces/dev?view=discussions). Jeśli uzyskasz satysfakcjonującą odpowiedź, umieść ją tutaj i zaznacz jako odpowiedź. –

Odpowiedz

4

Po rozmowie na Richfaces forum wymyślił to następujące rozwiązanie (dzięki do Brendana Healeya):

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 (częściowa)

... 

<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

Nie możesz podać odniesienia do dyskusji na forum? Dziękuję Ci. –

+0

https://developer.jboss.org/thread/204005?tstart=0 Znaleziono oryginalny temat. – Century