2014-10-06 82 views
1

我很新的JSF,並試圖實現使用<ui:repeat>分頁。我正在使用@ViewScoped,但目前我的狀態未保存。每次支持bean重置頁面信息並且不顯示下一頁。附上源代碼以供參考。怎麼做分頁的JSF 2

WorkItemList.xhtml

<?xml version='1.0' encoding='UTF-8' ?> 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<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" 
    xmlns:c="http://java.sun.com/jsp/jstl/core" 
    template="/WEB-INF/template/default.xhtml"> 

<ui:define name="content"> 
    <h:form id="form"> 

      <ui:repeat value="#{repeatPaginator.model}" var="listItem"> 
      <div> 
       <h:outputText value="#{listItem}"/> 
      </div> 
     </ui:repeat> 
     <h:commandButton value="&lt; prev" action="#{repeatPaginator.prev}"/> 
     <h:outputText value="#{repeatPaginator.pageIndex}/#{repeatPaginator.pages}"/> 
     <h:commandButton value="next &gt;" action="#{repeatPaginator.next}"/> 
     <h:inputHidden value="#{repeatPaginator.pageIndex}"/> 
    </h:form> 
</ui:define> 
</ui:composition> 

輔助Bean - RepeatPaginator.java

package test; 
@ManagedBean 
@ViewScoped 
public class RepeatPaginator implements Serializable{ 

    private static final long serialVersionUID = 1L; 
    private static final int DEFAULT_RECORDS_NUMBER = 2; 
    private static final int DEFAULT_PAGE_INDEX = 1; 
    private TestDelegate delegate; 
    private int records; 
    private int recordsTotal; 
    private int pageIndex; 
    private int pages; 
    private List<String> model; 
    public RepeatPaginator() { 
     delegate = new TestDelegate(); 
     this.records = DEFAULT_RECORDS_NUMBER; 
     this.pageIndex = DEFAULT_PAGE_INDEX; 
     // Get Model 
     this.model = delegate.fetchCurrentList(getFirst(), getFirst()+records); 
     this.recordsTotal = delegate.getListSize(); 

     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; 
     } 

     setModel(delegate.fetchCurrentList(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<String> getModel() { 
     if(model==null) 
      updateModel(); 
     return model; 
    } 

    public void setModel(List<String> model) { 
     this.model = model; 
    } 

    public void setPageIndex(int pageIndex) { 
     this.pageIndex = pageIndex; 
    } 
} 

代表 - TestDelegate.java

@ViewScoped 
public class TestDelegate { 

    private List<String> list = new ArrayList<String>(); 
    public TestDelegate() 
    { 
     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"); 
    } 

    public List<String> fetchCurrentList(int from, int to) 
    { 
     return list.subList(from, to); 
    } 

    public int getListSize() 
    { 
     return this.list.size(); 
    } 
} 

回答

0

@ViewScoped豆是不是「奇蹟般地出現所有的時間」。在請求結束時,它的值將被序列化並且bean被銷燬。

這導致豆的下一個請求開始一個重新構造(點擊旁邊)。您的容器將小心地反序列化存儲的值,以便返回bean的實際狀態。 但是:發生這種情況 Bean-Construction,意思是當您嘗試使用Bean的構造函數中的值時,什麼都不會被恢復。

將你的邏輯到您與@PostConstruct註釋的方法 - 那麼所有值將被加載,你可以獲取正確的結果。容器將調用@PostConstruct註釋的方法,一旦它恢復了bean的先前狀態。

當你開始使用ManagedProperties或CDI-注射這變得很重要。

public RepeatPaginator() { 
    //no serialized data available here, Good location to initialize some stuff 
    //that is independent. 
    delegate = new TestDelegate(); 
    this.records = DEFAULT_RECORDS_NUMBER; 
    this.pageIndex = DEFAULT_PAGE_INDEX; 
} 

@PostConstruct 
public void init() { 
     //Here the ViewScoped values are restored. We can start to use them. 

     // Get Model 
     this.model = delegate.fetchCurrentList(getFirst(), getFirst()+records); 
     this.recordsTotal = delegate.getListSize(); 

     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(); 
    } 
+0

感謝您的答案dognose,我已將代碼移至'@PostConstruct'方法。但我仍然有這個問題。我試圖調試代碼,我可以看到在點擊「Next」時,'@PostConstruct'內的模型仍然是NULL,而不是具有來自之前狀態的值。你能解釋一下爲什麼會出現這種情況嗎? – Adwin 2014-10-06 19:22:01

+0

我想通了..我錯誤地使用'@named'和'@managedbean'..現在它的工作正常..感謝您的快速反應。 – Adwin 2014-10-06 19:47:59

+0

@Adwin不客氣。 ps .:如果你對此感到滿意,你可以接受答案作爲正確的解決方案。 (激勵有幫助的人:P) – dognose 2014-10-06 19:54:13