p:datatable在ajax刷新后丢失排序列和顺序

jjr*_*oss 9 sorting ajax datatable primefaces jsf-2

我在页面上有一个按钮,可以通过AJAX请求刷新我的数据表.像这样的东西:

<h:form id="datatable">
<p:dataTable/>
</h:form>
<p:commandButton update=":datatable">
Run Code Online (Sandbox Code Playgroud)

这一切都很好,但是当表刷新时,它会恢复到不排序任何东西,同时仍然显示它是基于前一个值进行排序.换句话说,标题仍然突出显示,箭头仍指向排序方向,但实际上没有执行排序.显然这并不理想.

理想情况下,我希望组件在视图状态中保持其排序顺序,然后在AJAX请求期间提交适当的参数(以便正确定义排序).我错过了一个参数或什么?还有其他人有这个问题吗?

从表格预期排序时我可以看出它发布了以下选项:

<componentID>_sortDir
<componentID>_sortKey
<componentID>_sorting
<componentID>_updateBody
Run Code Online (Sandbox Code Playgroud)

当我刷新表单时,这不会发生.如果我只刷新表格也不会发生这种情况(我想通过直接更新组件可以解决问题).有没有办法让表格正确刷新?

srb*_*rbs 10

我为@ truemmer的解决方案写了一个扩展.他将排序顺序恢复为默认值,然后我将恢复到用户选择的上一个排序.

function postAjaxSortTable(datatable)
{
    var selectedColumn = datatable.jq.find('.ui-state-active');
    if(selectedColumn.length <= 0)
    {
        return;
    }
    var sortorder = "ASCENDING";
    if(selectedColumn.find('.ui-icon-triangle-1-s').length > 0)
    {
        sortorder = "DESCENDING";
    }
    datatable.sort(selectedColumn, sortorder);
}
Run Code Online (Sandbox Code Playgroud)

更新与truemmer相同的表是这样的:

<p:commandButton value="refresh" action="#{tableController.refreshPrices}" update="myTable" oncomplete="postAjaxSortTable(myTableWidget)" />
Run Code Online (Sandbox Code Playgroud)

编辑:Primefaces 4.0 MultiSort支持

function postAjaxSortTable(datatable) {
    var selectedColumn = undefined;

    // multisort support
    if(datatable && datatable.cfg.multiSort) {
        if(datatable.sortMeta.length > 0) {
            var lastSort = datatable.sortMeta[datatable.sortMeta.length-1];
            selectedColumn = $(document.getElementById(lastSort.col));
        }
    } else {
        selectedColumn = datatable.jq.find('.ui-state-active');
    }

    // no sorting selected -> quit
    if(!selectedColumn || selectedColumn.length <= 0) {
        return;
    }

    var sortorder = selectedColumn.data('sortorder')||"DESCENDING";
    datatable.sort(selectedColumn, sortorder, datatable.cfg.multiSort);
}
Run Code Online (Sandbox Code Playgroud)


Tim*_*ner 5

首先,PrimeFaces问题跟踪器上有一张开放票,它针对这个问题,但最近被标记为"无法修复".

不过,我找到了一个很好的解决方法.可以通过在数据表的小部件上调用未记录的JavaScript方法来触发PrimeFaces表的排序.以下可能不适用于PrimeFaces的未来版本,但它适用于3.4.2:

只需将以下内容添加到组件中即可触发更新:

oncomplete="myTableWidget.sort($(PrimeFaces.escapeClientId('#{p:component('sortColumnId')}')), 'ASCENDING')"
Run Code Online (Sandbox Code Playgroud)

该表可能如下所示:

<p:dataTable id="myTable"
             widgetVar="myTableWidget"
             value="#{myArticles}"
             var="article"
             sortBy="#{article.price}"
             sortOrder="ASCENDING">
    ...

    <p:column id="price" sortBy="#{article.price}">
        <f:facet name="header">
            <h:outputText value="Price" />
        </f:facet>
        <h:outputText value="#{article.price}" />
    </p:column>

</p:dataTable>
Run Code Online (Sandbox Code Playgroud)

所以更新表可以这样工作.

<p:commandButton value="refresh" action="#{tableController.refreshPrices}" update="myTable" oncomplete="myTableWidget.sort($(PrimeFaces.escapeClientId('#{p:component('price')}')), 'ASCENDING')" />
Run Code Online (Sandbox Code Playgroud)

  • 在PF6.1中,sortorder必须是一个数字:1/-1表示'ASCENDING'/'DESCENDING'. (2认同)

Fal*_*lup 3

编辑:

下面发布的解决方案(LazyTable)适用于由 LazyDataModel 支持的 p:dataTable。每次更新/刷新所需表后都会调用重写加载方法,并且它可以正确处理排序。简单 p:dataTable 的问题在于它仅在第一次加载时或单击排序列后执行预定义排序。这是简单表的正常行为。

那么简单的表格有哪些可能性:

  • 更新后不要对表进行排序,而是删除排序列,这样最终用户就不会被误导。将其添加到更新按钮的操作侦听器或操作方法中:

    UIComponent table  = FacesContext.getCurrentInstance().getViewRoot().findComponent(":dataTablesForm:dataTableId");
    table.setValueExpression("sortBy", null);
    
    Run Code Online (Sandbox Code Playgroud)
  • 通过脚本手动更新表的排序。这不是最好的解决方案,但 primefaces 不提供任何客户端功能来“重新排序”表。基本上您知道一次只能对一列进行排序,并且该列具有 .ui-state-active。您可以在脚本中使用它并触发对该列的 2 次单击(1. 单击 - 其他排序顺序,2. 单击 - 返回当前排序顺序)。

     <h:form id="mainForm">  
    <div id="tableDiv">
       <p:dataTable id="dataTable" var="item" value="#{testBean.dummyItems}">
          .
          .
          .
       </p:dataTable> 
       <p:commandButton value="Refresh" oncomplete="refreshSort();" update=":mainForm:dataTable"/>
     </div>
    
    Run Code Online (Sandbox Code Playgroud)

    和脚本函数:

    function refreshSort(){
    jQuery('#tableDiv').find('.ui-state-active').trigger('click');
    jQuery('#tableDiv').find('.ui-state-active').trigger('click');
    }
    
    Run Code Online (Sandbox Code Playgroud)

我知道这不是最好的解决方法,但它确实有效。您可以用它作为灵感来做得更好。

惰性表

恕我直言,最正确的方法是直接更新您想要的组件。例如:

<h:form id="dataTableForm">
  <p:dataTable id="dataTableToUpdate">
    .
    .
    .
  </p:dataTable>
  <p:commandButton value="Refresh" update=":dataTableForm:dataTableToUpdate" />
</h:form>
Run Code Online (Sandbox Code Playgroud)

在这种情况下它应该可以正常工作(我想这是您的目的):使用 p:dataTable 打开 .xhtml,对某些列进行排序(保持 Facelet 打开),例如从另一个 .xhtml 更新 dataTables 数据,单击刷新按钮。数据表应该以正确的(之前选择的)排序顺序显示您添加的值 - 排序是在更新后执行的。

希望有帮助!