2012-08-13 18 views
6

ここにJSFページングに関する記事がたくさんあることは知っていますが、どれも私を満たしていません。JSF、RichFaces、ページ区切り

かなり大きなデータをページに分割するには、RichFaces Dataスクロールコンポーネントを使用するつもりでした。

これは適しているようですが、「人為的」ページネーションのように見えます。

ここで私が気に入らないのは、すべてのデータを読み込んでその一部を表示するという点です。少なくともそれはそうするように見えます。私が間違っているなら私を訂正してください。

豊かな顔にはすてきなデモがありますが、何らかの理由でBeanの定義をスキップします.XHTMLのみです。 私はExtendedDataModelのいくつかの言及を見ましたが、私が見つけた唯一の例は私に感銘を与えませんでした。 なぜ私は5つの画面コードを持っているだけでデータのサブセットを表示していますか?

正直なところ、ページ分割のような単純な質問は、JSFでは非常に複雑で、私は本当に理由を知りません。

は、だから私の質問は以下のとおりです。 1はRichFacesの中で(私はなど、実際のデータは状態 - 現在のページを表示しない意味)セッションにそれを格納することなく、データ 2の1ページだけをロードすることも可能である

私はすでに私のプロジェクトでそれを使用し、RichFacesのフォーラムで話した後、事前

+0

これは興味深い質問ですが、RichFacesチーム自身が回答しなければなりません。 [RichFaces Developer Forum](https://community.jboss.org/ja/richfaces/dev?view=discussions)に投稿すると良いでしょう。そこに満足のいく回答が得られたら、ここに投稿して回答としてマークしてください。 –

答えて

4

に他のsomethin

ありがとうへの依存を導入していない、何がこの次のソリューションを思いついただけRichFacesのlibにに興味がある(ありがとうブレンダン・ヒーリー):

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(部分)

... 

<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

フォーラムでディスカッションを参照できませんでしたか?ありがとうございました。 –

+0

https://developer.jboss.org/thread/204005?tstart=0 元のトピックが見つかりました。 – Century