2012-12-18 52 views
4

我有一個使用JSF2.0,Spring3和Hibernate4的應用程序。Primefaces數據表分頁不起作用

我在Primefaces 3.4.2數據表中顯示值,問題是當我單擊分頁時,數據錶行始終保留在前10條記錄中。它不顯示接下來的10條記錄。

我的DataTable代碼

<h:form> 
     <p:dataTable id="dataTable" var="req" value="#{reqMB.myList}" 
      paginator="true" rows="10" 
      paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}" 
      rowsPerPageTemplate="5,10,15"> 
      <f:facet name="header">   

     </f:facet> 
      <p:column> 
       <f:facet name="header"> 
        <h:outputText value="XXX" /> 
       </f:facet> 
       <h:outputText value="#{req.bbbb}" /> 
      </p:column> 

      <p:column> 
       <f:facet name="header"> 
        <h:outputText value="XXXXS" /> 
       </f:facet> 
       <h:outputText value="#{req.kkjj}" /> 
      </p:column> 

      <p:column> 
       <f:facet name="header"> 
        <h:outputText value="XXXXXOO" /> 
       </f:facet> 
       <h:outputText value="#{req.nnnn}" /> 
      </p:column> 

      <p:column> 
       <f:facet name="header"> 
        <h:outputText value="XXXXKK" /> 
       </f:facet> 
       <h:outputText value="#{req.kkkk}" /> 
      </p:column> 

      <p:column> 
       <f:facet name="header"> 
        <h:outputText value="XKKKK" /> 
       </f:facet> 
       <h:outputText value="#{req.pppp}" /> 
      </p:column> 

      <p:column> 
       <f:facet name="header"> 
        <h:outputText value="LLLL" /> 
       </f:facet> 
       <h:outputText value="#{req.llll}" /> 
      </p:column> 
     </p:dataTable> 
    </h:form> 

ManagedBean

@Named("reqMB") 
@Scope("request") 
public class MyBean implements Serializable { 

    private static final long serialVersionUID = 1L; 

    @Inject 
    MyService myService; 

    List<MyClass> myList; 


    public List<MyClass> getMyList() { 
     try { 
      myList= new ArrayList<MyClass>(); 
      myList.addAll(getMyService().getMymethod()); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
     return myList; 
    } 

我怎樣才能解決這個問題?

更新1

我注意到,當我顯示的記錄極少數分頁工作正常,但是當我展示超過1300多條記錄,那麼分頁不起作用。

+0

我不認爲這是一個好主意,使用請求範圍表分頁...因爲你不能使用CDI視圖,我認爲會話範圍是你應該使用的範圍 – Daniel

+0

@Daniel感謝您的建議,我確實設法使用[this]實現視圖範圍(http://cagataycivici.wordpress.com/2010/02/17/port-jsf-2-0s-viewscope-to-spring-3-0/) – user75ponic

回答

2

我剛剛嘗試了30000條記錄,它工作正常。值得注意的一件事是,getMyList方法被調用了很多次(在我的情況下是6次渲染響應階段),每次它被稱爲你的bean獲取/產生一個全新的列表,這可能是導致問題(雖然我試圖在我的getter方法中生成一個新列表,但它工作正常)。

一般來說,建議不要在那裏放置任何業務邏輯相關的代碼。相反在許多情況下,最好是在@PostConstruct方法或其他地方填充列表。請參閱BalusC製作的帖子,這可能會有所幫助。 Why JSF calls getters multiple times 你也可以閱讀這個懶加載 Efficient JSF Pagination

下面是我的測試代碼:

<h:body> 
    <h:form> 
     <p:dataTable id="dataTable" var="car" value="#{tableBean.cars}" 
        paginator="true" rows="10" 
        paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}" 
        rowsPerPageTemplate="5,10,15"> 
      <f:facet name="header"> 
       Ajax Pagination 
      </f:facet> 

      <p:column> 
       <f:facet name="header"> 
        <h:outputText value="Model" /> 
       </f:facet> 
       <h:outputText value="#{car.model}" /> 
      </p:column> 

      <p:column> 
       <f:facet name="header"> 
        <h:outputText value="Manufacturer" /> 
       </f:facet> 
       <h:outputText value="#{car.manufacturer}" /> 
      </p:column> 

      <p:column> 
       <f:facet name="header"> 
        <h:outputText value="Other Information" /> 
       </f:facet> 
       <h:outputText value="#{car.otherInformation}" /> 
      </p:column> 
     </p:dataTable> 
    </h:form> 
    <ui:debug hotkey="x"/> 
</h:body> 

這是支持bean:

@ManagedBean 
@RequestScoped 
public class TableBean implements Serializable { 

    private List<Car> cars; 

    @PostConstruct 
    public void init() { 
     System.out.println("A new backing bean has been created"); 
     cars = new ArrayList<Car>(); 
     populateRandomCars(cars, 300000); 
    } 

    private void populateRandomCars(List<Car> list, int size) { 
     for (int i = 0; i < size; i++) { 
      list.add(new Car(i, i, UUID.randomUUID().toString())); 
     } 
    } 

    public List<Car> getCars() { 
//If i populate the list here I can still get the correct result. 
//  cars = new ArrayList<Car>(); 
//  populateRandomCars(cars, 30000); 
     return cars; 
    } 

    public void setCars(List<Car> cars) { 
     this.cars = cars; 
    } 
} 

最後的模型類:

public class Car { 
    private int manufacturer; 
    private int model; 
    private String otherInformation; 

    public Car(int manufacturer, int model, String otherInformation){ 
     this.manufacturer = manufacturer; 
     this.model = model; 
     this.otherInformation = otherInformation; 
    } 

    //Getters and Setters 
} 
+0

謝謝對於這個建議。當你獲取30000條記錄時,你使用@PostConstruct方法嗎? – user75ponic

+0

你能不能提供你的工作版本獲取30000條記錄? – user75ponic

+0

嗨@Polppan我已經更新了我的答案,包括我的代碼:) –

2

的問題是,你每次創建數據表,當你以這種方式使用:

public List<MyClass> getMyList() { 
    ... 
    myList= new ArrayList<MyClass>(); 
    ... 
} 

您需要初始化,例如,你可以使用@PostContruct

@PostConstruct 
public void init() { 
    myList= new ArrayList<MyClass>(); 
} 

然後第一myList中的屬性,你可以使用:

public List<MyClass> getMyList() { 
    return myList 
} 

這將作品甚至懶的DataTable