如何使用Ajax更新PrimeFaces dataTable底部的项目?

4
这是我拥有的表格的可视化效果:
+---------+------------+-------------------+
| Header1 |  Header2   | Header3           |
+---------+------------+-------------------+
| Row A   |  Input A   | 计算出的输出结果 A |
| Row B   |  Input B   | 计算出的输出结果 B |
| 等等..   |  等等..     |  等等..             |
+---------+------------+-------------------+
|    总计:          计算出的总输出结果  |
+------------------------------------------+
以下是简化的代码:
<p:dataTable id="myTable" value="#{myBean.someList}"
    var="currentItem">

    <p:column headerText="Header1">
        <h:outputText value="#{currentItem.name}" />
    </p:column>

    <p:column headerText="Header2">
        <pe:inputNumber value="#{currentItem.inputVal}">
            <p:ajax event="change" listener="#{myBean.changeListener}"
                update="outputVal outputTotal" />
        </pe:inputNumber>
    </p:column>

    <p:column headerText="Header3">
        <h:outputText id="outputVal" value="#{currentItem.outputVal}" />
    </p:column>

    <f:facet name="footer">
        Total:
        <h:outputText id="outputTotal" value="#{myBean.total}" />
    </f:facet>

</p:dataTable>
myBean.someList是一个具有一个字符串和两个整数的ArrayList<SomeOtherBean>,只有getter和setter方法。 myBean.changeListener用于计算给定行的第二个整数以及所有行的总计。当我在其中一个输入框中输入并失去焦点时,侦听器会被调用并进行计算,但在屏幕上,第三列中的值会更改,但总数仍然为零。我相当确定这与PrimeFaces将每个输入和输出的生成ID附加到行索引有关,但我无法找到如何访问页脚中的输出(其生成的ID为mainForm:myTable:0:outputTotal)。
现在,我可以只更新父表。 但是,每当接收焦点的输入是更新目标的一部分时,焦点就会丢失,并且我必须遵守极其严格的无障碍规则,使此表格在键盘上友好(输入数字,制表符,输入数字,制表符等)。 我已经尝试过:
- update =“:outputTotal”(出现异常无法找到具有标识符...的组件) - update ="myTable:0:outputTota"(相同异常) - update ="myTable:outputTotal"(未更新,总数保持为零) - 将文本包装在面板组中并更新该组(未更新)
(PrimeFaces 3.5.0与MyFaces未知版本)
2个回答

11

你不能在表格内部实际更新表格的值。然而,你可以使用 p:remoteCommand 来实现这一点。此外,我可能会在整个表格上使用 cellEdit 事件(而不是单个 p:ajax 在你的 pe:inputNumber 上)。总体结果将是:

<p:remoteCommand name="refreshFooter" update=":formName:outputTotal"/>
...
<p:dataTable id="myTable" value="#{myBean.someList}" var="currentItem">

    <p:column headerText="Header1">
        <h:outputText value="#{currentItem.name}" />
    </p:column>

    <p:column headerText="Header2">
        <pe:inputNumber value="#{currentItem.inputVal}">
            <p:ajax event="change" listener="#{myBean.changeListener}" process="@this"
                oncomplete="refreshFooter();" update="outputVal"/>
        </pe:inputNumber>
    </p:column>

    <p:column headerText="Header3">
        <h:outputText id="outputVal" value="#{currentItem.outputVal}" />
    </p:column>

    <f:facet name="footer">
        Total:
        <h:outputText id="outputTotal" value="#{myBean.total}" />
    </f:facet>

</p:dataTable>
请注意,您可能需要在p:ajax中添加partialSubmit =“true”,这样您只提交组件的数据。如果您喜欢cellEdit事件的想法,则需要使dataTable可编辑,并在p:dataTable中添加以下内容,并且删除pe:inputNumber内部的p:ajax
<p:ajax event="cellEdit" partialSubmit="true" listener="#{myBean.onCellEdit}" 
    process="@this" oncomplete="refreshFooter();"/>

祝你好运!


0

更新PrimeFaces

这个问题最终在PrimeFaces 11或PrimeFaces Elite 8.0.8 / 10.0.1中得到了修复。使用PrimeFaces 11+,您可以在数据表上使用partialUpdate="false"。这个修复的缺点是它也会更新标题(和过滤器),所以当您正在输入时,它可能会为您更新过滤器输入。您可以在过滤器事件上设置一个delay来改善这个问题,但效果不会消失,只是不那么明显。

请参见:

PrimeFaces.ab 而不是 p:remoteCommand

如果您不想创建 p:remoteCommand 来更新数据表格filter事件上的组件(我也不想这样做), 您可以使用:

<p:ajax event="filter"
        oncomplete="PrimeFaces.ab({source:'#{component.clientId}',process:'@none',update:'componentToUpdate'})"/>

没错,这看起来有点凌乱,但是你可以创建一个自定义的EL函数来将其简化为:

<p:ajax event="filter"
        oncomplete="#{my:ajaxUpdate('componentToUpdate')}"/>

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