p:column sortBy 值表达式未对列索引求值

p:column sortBy value expresson not evaluating to column index

我在惰性数据 table 的固定列中遇到问题,其中混合了固定列和动态列。这是 table:

<p:dataTable id="table" value="#{formController.lazyModel}" var="record" rowKey="#{record.get(0)}" widgetVar="tableWidget"
         lazy="true" selection="#{formController.selectedRecord}" selectionMode="single" style="#{formController.tableStyle} min-width: 120px;"
         scrollable="true" scrollHeight="600" scrollWidth="100%" emptyMessage="#{sessionController.itemFormLabels['table_no_entries_msg']}" editable="true"
         paginator="true" rows="50" rowsPerPageTemplate="25,50,100" paginatorPosition="bottom" filterDelay="500"
         paginatorTemplate="{RowsPerPageDropdown} {FirstPageLink} {PreviousPageLink} {CurrentPageReport} {NextPageLink} {LastPageLink}">

<p:ajax event="rowEdit" listener="#{formController.onRowEdit}" update=":alowAddNewRecord :formTableForm:buttonPanel" />
<p:ajax event="rowEditCancel" onsuccess="cancelEditing();" />
<p:ajax event="page" onstart="blockTableInput();" oncomplete="enbleTableInput();" />

<f:facet name="header">

    <p:commandButton id="insertButton" value="#{sessionController.itemFormLabels['add_record_button']}" icon="fa fa-plus"
                     actionListener="#{formController.insertRecord}" disabled="#{not formController.alowAddNewRecord}"
                     title="#{sessionController.itemFormLabels['add_record_tip']}" onclick="saveLastRow();PF('tableWidget').clearFilters();"
                     update=":alowAddNewRecord :formTableForm:table :formTableForm:buttonPanel :growlMessages" />

</f:facet>

<p:column headerText="ID" sortBy="#{record[0]}" filterBy="#{record[0]}" filterMatchMode="contains" exportable="false"
          style="width: 50px; font-size: 12px !important;" rendered="#{formController.formColumnList.get(0).visible}">

           ...

</p:column>

<p:columns var="column" value="#{formController.columnsInfo}" columnIndexVar="colIndex" exportable="false"
           sortBy="#{record[column.columnIndex]}" filterBy="#{record[column.columnIndex]}" filterMatchMode="contains"
           rendered="#{formController.formColumnList.get(column.columnIndex).visible}"
           filterStyle="width: 90%" style="#{formController.columnsCustomStyles.get(column.columnIndex - 1)} font-size: 12px !important;">

           ...

</p:columns>

<p:column headerText="report header" sortBy="#{record[formController.noColumns + 1]}" exportable="false"
          filterBy="#{record[formController.noColumns + 1]}" filterMatchMode="contains" style="width: 50px; font-size: 12px !important;"
          rendered="#{formController.tableInfo.tableType eq 1 and formController.formColumnList.get(formController.noColumns + 1).visible}">

          ...

</p:column>

<p:column headerText="user created" sortBy="#{record[formController.noColumns + formController.factColDelta + 1]}" exportable="false"
          filterBy="#{record[formController.noColumns + formController.factColDelta + 1]}" filterMatchMode="contains"
          style="width: 100px; font-size: 12px !important;" rendered="#{formController.formColumnList.get(formController.noColumns + formController.factColDelta + 1).visible}">

          ...

</p:column>

<p:column headerText="date created" sortBy="#{record[formController.noColumns + formController.factColDelta + 2]}" exportable="false"
          filterBy="#{record[formController.noColumns + formController.factColDelta + 2]}" filterMatchMode="contains"
          style="width: 100px; font-size: 12px !important;" rendered="#{formController.formColumnList.get(formController.noColumns + formController.factColDelta + 2).visible}">

          ...

</p:column>

<p:column headerText="user modified" sortBy="#{record[formController.noColumns + formController.factColDelta + 3]}" exportable="false"
          filterBy="#{record[formController.noColumns + formController.factColDelta + 3]}" filterMatchMode="contains"
          style="width: 100px; font-size: 12px !important;" rendered="#{formController.formColumnList.get(formController.noColumns + formController.factColDelta + 3).visible}">

          ...

</p:column>

<p:column headerText="date modified" sortBy="#{record[formController.noColumns + formController.factColDelta + 4]}" exportable="false"
          filterBy="#{record[formController.noColumns + formController.factColDelta + 4]}" filterMatchMode="contains"
          style="width: 100px; font-size: 12px !important;" rendered="#{formController.formColumnList.get(formController.noColumns + formController.factColDelta + 4).visible}">

          ...

</p:column>

<p:column style="width:32px" exportable="false">
    <p:rowEditor />
</p:column>

如果我对动态列调用排序,一切都很好。 sortBy 值表达式:#{record[column.columnIndex]} 的计算结果为列索引并且排序正常。 而如果我在固定列上调用排序,假设是第一个列,值表达式 #{record[0]} 的计算结果不是列索引 0,而是字符串 'record[0]'。 这可以在调用排序时抛出的 NumberFromatException 中看到:

12:09:52,336 SEVERE [javax.enterprise.resource.webcontainer.jsf.application] (default task-1) Error Rendering View[/public/item_form.xhtml]: java.lang.NumberFormatException: For input string: "record[0]" at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)

我正在使用 Primefaces 6.2

我已经弄清楚哪里出错了。我已经实现了一个懒惰的 table,在这样做的时候,一个人负责编写自己的懒惰模型 class,它扩展了 LazyDataModel class,它也负责排序和过滤。我已经完全按照要求做了,但是我忘了实现对我的非动态列的处理。

所以有两种方案:

  1. 使用有关我的静态列的信息(列表中的位置、数据类型等)增强我的惰性 class,并添加对这些列进行排序和过滤的具体实现。

  2. 将我的静态列添加到 p:columns 标记中呈现的列表中(即放弃非动态列),并将静态列的列样式和其他信息添加到描述动态列的相应列表。这样一来,就不必向惰性数据模型添加特定于实现的代码。

第二种解决方案更简洁。希望这会启发其他犯过同样错误的人。