4

我有一个使用 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>

托管豆

@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 条记录时,分页不起作用。

4

2 回答 2

2

我刚刚尝试了 30000 条记录,它工作正常。值得注意的一件事是 getMyList 方法被多次调用(在我的情况下,在渲染响应阶段是 6 次)并且每次调用它时,您的 bean 都会获取/生成一个全新的列表,这可能是导致问题(尽管我尝试在我的 getter 方法中生成一个新列表,但它工作正常)。

一般来说,建议不要放任何业务逻辑相关的代码。相反,在许多情况下,最好在 @PostConstruct 方法或其他地方填充列表。请参阅 BalusC 发布的帖子,它可能会有所帮助。 为什么 JSF 多次调用 getter 你也可以阅读这篇文章以了解延迟加载 高效的 JSF 分页

以下是我的测试代码:

<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 
}
于 2012-12-19T08:59:49.013 回答
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
}

这甚至适用于惰性数据表

于 2013-05-03T03:48:38.880 回答