我有一个使用JSF2.0,Spring3和Hibernate4的应用程序。
我在Primefaces 3.4.2数据表中显示值,问题是当我点击分页时,数据表行始终保留在前10条记录中。它不显示接下来的10条记录。
我的数据表代码
<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 :(得分: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
}
答案 1 :(得分:2)
问题在于,当您以这种方式使用时,每次都会创建数据表:
public List<MyClass> getMyList() {
...
myList= new ArrayList<MyClass>();
...
}
您需要初始化第一个myList属性,例如您可以使用@PostContruct
@PostConstruct
public void init() {
myList= new ArrayList<MyClass>();
}
然后,您可以使用:
public List<MyClass> getMyList() {
return myList
}
这甚至适用于Lazy数据表