PrimeFaces中的datatable排序无法工作?

16

datatable在PrimeFaces中无法排序。请给予建议。

以下是我的.xhtml文件

<h:form>

  <p:dataTable style="width: 60%" id="dt1" value="#{bean.list}" var="entry" first="0" paginator="true" rows="10" paginatorTemplate="{CurrentPageReport}  {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}" rowsPerPageTemplate="5,10,15" emptyMessage="No cars found with given criteria" >

    <f:facet name="header">
      <h2>Cars View</h2>
    </f:facet>

    <p:column sortBy="#{entry.carno}" filterBy="#{entry.carno}">
      <f:facet name="header">
        <h:outputText value="Car Number" />
      </f:facet>
      <h:outputText value="#{entry.carno}"></h:outputText>
    </p:column>

    <p:column sortBy="#{entry.carsettings['car-model']}" filterBy="#{entry.carsettings['car-model']}">
      <f:facet name="header">
        <h:outputText value="Car Model"/>
      </f:facet>
      <h:outputText value="#{entry.carsettings['car-model']}"></h:outputText>
    </p:column>

    <p:column sortBy="#{entry.carsettings.year}" filterBy="#{entry.carsettings.year}">
      <f:facet name="header">
        <h:outputText value="Car Year"/>
      </f:facet>
      <h:outputText value="#{entry.carsettings.year}"></h:outputText>
    </p:column>

    <p:column sortBy="#{entry.carsettings.color}" filterBy="#{entry.carsettings.color}">
      <f:facet name="header">
        <h:outputText value="Car Color"/>
      </f:facet>
      <h:outputText value="#{entry.carsettings.color}"></h:outputText>
    </p:column>
  </p:dataTable>
</h:form>

@Sean

看下面的代码:

  • 汽车列表

    <ui:composition template="/template.xhtml">
        <ui:define name="content">
            <f:view>
                <f:event type="preRenderView" listener="#{MyBackingBean.load}"></f:event>
                <center>
                    <h1>Car View</h1>
                    <h:outputText value="No data found" style="font-size: 15px;font-family: Arial, Verdana,Helvetica, sans-serif" rendered="#{MyBackingBean.noDataExist}"></h:outputText>
                    <h:form id="dataform1">
                        <p:dataTable var="item" value="#{MyBackingBean.dataList}" dynamic="true" paginator="true" rows="2" id="table"  style="width:60%"
                                     rendered="#{!MyBackingBean.noDataExist}" >
                            <p:column sortBy="#{item.id}" filterBy="#{item.id}">
                                <f:facet name="header">
                                    <h:outputText value="ID" />
                                </f:facet>
                                <h:outputText value="#{item.id}" />
                            </p:column>
                            <p:column sortBy="#{item.carsettings['car-color']}" filterBy="#{item.carsettings['car-color']}">
                                <f:facet name="header">
                                    <h:outputText value="Color" />
                                </f:facet>
                                <h:outputLink target="_blank" value="http://#{item.carsettings['car-color']}">
                                    <h:outputText value="#{item.carsettings['car-color']}" />
                                </h:outputLink>
                            </p:column>
                            <p:column sortBy="#{item.carsettings.model}" filterBy="#{item.carsettings.model}">
                                <f:facet name="header">
                                    <h:outputText value="Model" />
                                </f:facet>
                                <h:outputText value="#{item.carsettings.model}" />
                            </p:column>
                            <p:column sortBy="#{item.carsettings.manufacturer}" filterBy="#{item.carsettings.manufacturer}">
                                <f:facet name="header">
                                    <h:outputText value="Manufacturer" />
                                </f:facet>
                                <h:outputText value="#{item.carsettings.manufacturer}" />
                            </p:column>
                        </p:dataTable>
                    </h:form>
                </center>
            </f:view>
        </ui:define>
    </ui:composition>
</h:body>

以上代码中排序不起作用

请帮忙


请提供更多信息。发生了什么?什么都没有发生还是发生了意外的事情?您的页面剩下的部分是什么样子的?您的后端 bean 的范围是什么? - Sean
@user617966:另外,请注意,目前在Primefaces的任何版本中,对非拉丁UTF-8字符进行排序(和过滤)是不起作用的。仅拉丁字符能被排序。 - ChuongPham
我遇到了同样的问题,但alfonx的评论是解决方法。 - Einar
我有同样的问题,你能解决这个问题吗? - Hanynowsky
7个回答

45

primefaces后台Bean(ViewScoped!)必须持有自己的行列表。例如,如果每次请求p:dataTable:value时都查询数据库,则排序将无法正常工作。

解决方案:从数据库收集List,并将其保存在后备Bean中的本地List变量中。

public List<Row> getDataTable() {
    if (tableDataList == null)
        tableDataList = loadListOnce();
    return tableDataList;
}

这解决了我的问题,谢谢。希望它也能解决楼主的问题。 - Einar
4
@alfonx解决了我的问题。可惜PF用户指南中没有提到对备用列表的依赖。 - kostja
1
代码示例在bkomac的答案中。 - Nice Books

11

问题是:

<f:event type="preRenderView" listener="#{MyBackingBean.load}"></f:event>

<p:dataTable/> 上,通过 PhaseId.APPLY_REQUEST_VALUES 对列表进行排序,在 PhaseId.RENDER_RESPONSE 中使用 <f:event type"preRenderView"/> 重新加载列表,因此会丢失排序。

解决方法:使用 <f:event type="postAddToView"/>

<f:event type="postAddToView" listener="#{MyBackingBean.load}" />

这将在 <p:dataTable/> 进行排序之前重新加载 PhaseId.RESTORE_VIEW 中的列表。

测试使用了PrimeFaces 版本 3.1.1Mojarra 2.1.8


这个很好用。我之前使用的是f:event type="preRenderView",改成postAddToView后效果非常棒!谢谢。 - Catfish
1
我们应该把这个放在哪里? - Koray Tugay

6
如果您在getter中填充表格,则排序将无法工作(如上所述)。您应该像这样在getter中放置内容:
public List<Row> getTableData() {
    if (tableDataList == null)
        tableDataList = dao.getTableData();
    return tableDataList;
}

如果你想要刷新(datatable)数据表格,可以通过将tableDataList赋值为null来重置(刷新)"cash"。


2
加上 if(tableDataList == null) 对我很有帮助,谢谢。 - Nice Books

1

我的一个问题是,在我的后台Bean为sessionScoped时,排序出了问题。不确定你的确切问题是什么,但如果你点击排序按钮没有任何反应,请尝试将范围更改为@ViewScoped。


不,Sean。我已经尝试将我的后备bean更改为@ViewScoped,但没有结果。当我点击排序图标时,什么也不会发生。有什么建议吗? - user617966
我需要看更多你的代码。从你发布的内容来看,它似乎应该可以工作。如果你在这里找不到答案,你也应该尝试一下PrimeFaces支持论坛。 - Sean
对我来说很有效,viewscope和sessionscope都按预期工作。 - Galilo Galilo

1

我的服务包括:

public List<PlayerEntity> getAllPlayers() {
    return playerDao.readAll();
}

但那是错误的,因为当我从表格中调用getAllPlayers()时。

<p:dataTable id="data" value="#{myBean.allPlayers}"/>

我从DAO中获取了刷新后的数据,但仍然是无序的。因此,我创建了一个列表字段和更新列表的方法。

private List<PlayerEntity> allPlayers = new ArrayList<PlayerEntity>();  

public void updateAllPlayers(){
    this.allPlayers = playerDao.readAll();
}

我在bean初始化时运行的是哪个方法?

public void setPlayerDao(PlayerDao playerDao) {
    this.playerDao = playerDao;
    updateAllPlayers();
}

并且在添加、删除或修改列表之后

public boolean createPlayer(PlayerEntity playerEntity) {
    (...)
    updateAllPlayers();
    return true;
}

现在我的服务有:
public List<PlayerEntity> getAllPlayers() {
    return this.allPlayers;
}

并且这解决了我在Primefaces表格中排序数据的问题。

0

你尝试过@SessionScoped吗?对我来说很有效,希望这可以帮到你。


不是我的问题!无论是ViewScoped还是RequestScoped都不行! - Hanynowsky

-1

我不知道这是否涉及到你的问题。这是一个PrimeFaces的问题。数据表格排序上的一个bug。在这里看一下: https://code.google.com/archive/p/primefaces/issues/2476

有一些解决方法:

  1. 你可以为你的数据表格使用lazyDataModel,这可以解决问题。

  2. 你可以强制排序顺序。

在你的数据表格中捕获排序事件。

<p:dataTable style="width: 60%" id="dt1" value="#{bean.list}" var="entry" first="0" paginator="true" rows="10" paginatorTemplate="{CurrentPageReport}  {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}" rowsPerPageTemplate="5,10,15" emptyMessage="No cars found with given criteria" >
<p:ajax event="sort" listener="#bean.sortListener}" />

在你的托管Bean中,你设置了一个排序字符串来添加到你的查询中。
private String orderBy = "";

public void sortListener(SortEvent event) {
    String orderColumn = event.getSortColumn().getValueExpression("sortBy").getExpressionString();

    //you will get the content of the attribute SortBy of the column you clicked on, like #{entry.carno}
    orderColumn = orderColumn.replace("#{entry.", "");
    orderColumn = orderColumn.replace("}", "");
    orderBy = " order by " + orderColumn + (event.isAscending()? " asc " : " desc ");
}

public List<Car> getList(){
    String query = "[...your query...]" + orderBy;
    ...[execute your query and get your ordered list]
}

即使如此,这也不被视为错误,因为它是“不修复”的,并且已经存在5年了。 - Kukeltje

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接