2014-10-06 18 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