【问题标题】:Ajax call removes value from bean on JSF pageAjax 调用从 JSF 页面上的 bean 中删除值
【发布时间】:2020-06-12 15:33:19
【问题描述】:

第一次在堆栈溢出上发帖,如果我在提问时没有达到预期的标准,敬请见谅。

我们有一个 JSF 页面,其中包含一个 html 表格(代码如下)。该表包含 5 列,需要用户响应(例如选择列表、数字输入等)。这个想法是用户从列 id 'condition' 的选择列表中选择,然后为列 id 'restored' 选择一个选项。如果restored 设置为yes,那么我们希望调用ajax 并启用最后3 列“restored date”、“professionally”和“restorationCost”。

但是我们发现,当用户从“条件”中选择他们的选项,然后在“已恢复”中选择“是”时,最后 3 列将正确启用,但在“条件”中输入的值被删除,并且放回null。

将日志添加到 bean(具有通用 getter/setter 方法)我可以看到该值最初被设置,但随后在 ajax 调用之后再次设置为 null。此外,此值仅在第一次设置为 null,如果在表的同一行或表中的新行上重复相同的步骤,则该值会如我们预期的那样正确保留。

一个可行的破解解决方案是在 bean 中的 set 方法中添加一个 if 查询,以仅在传递给该方法的字符串不为 null 时设置值,但这不是我们想要使用的解决方案,除非它是不得已。

任何人都可以提供任何帮助或提供任何理由来说明它为什么会这样吗?谢谢。

使用 Primefaces 8.0 版并且 bean 是会话范围的。

<ui:composition xmlns="http://www.w3.org/1999/xhtml" xmlns:f="http://xmlns.jcp.org/jsf/core" xmlns:h="http://xmlns.jcp.org/jsf/html"
    xmlns:p="http://primefaces.org/ui" xmlns:ui="http://xmlns.jcp.org/jsf/facelets">
    <p:outputPanel id="conditions">
        <p>CONDITION AND RESTORATIONS</p>
        <p>Condition value key:</p>
        <ui:repeat var="con" value="#{sessionDataWrapper.sessionData.classicCarDto.conditions}" varStatus="status">
            <br/><h:outputText styleClass="mandatoryText" value="#{con.value} - #{con.name}: #{con.description}"/>
        </ui:repeat>
        <br/>
        <table id="conditionsTable" class="conditionsTable">
            <tr>
                <th></th>
                <th id="conditionHeader" class="tableHeader">CONDITION</th>
                <th id="restoredHeader" class="tableHeader">RESTORED</th>
                <th id="dateHeader" class="tableHeader">DATE</th>
                <th id="professionallyHeader" class="tableHeader">PROFESSIONALLY</th>
                <th id="costHeader" class="tableHeader">COST</th>
            </tr>
            <tbody>
            <ui:repeat id="conditionsTableSub" var="c" value="#{dto.components}" varStatus="status">
                <tr>
                    <td class="tableFieldName">#{c.name}</td>
                    <td>
                        <p:selectOneMenu class="tableDropdown" id="condition" value="#{c.condition}">
                            <f:selectItem itemLabel="Select" itemValue=""/>
                            <f:selectItems value="#{dto.conditions}" var="condition" itemLabel="#{condition.value}" itemValue="#{condition.value}" />
                            <p:ajax event="change" process="@this" />
                        </p:selectOneMenu>  
                    </td>
                    <td>
                        <p:selectOneMenu class="tableDropdown" id="restored" value="#{c.restored}">
                            <f:selectItem itemLabel="Select" itemValue=""/>
                            <f:selectItem itemLabel="Yes" itemValue="true"/>
                            <f:selectItem itemLabel="No" itemValue="false"/>
                            <f:ajax event="change" process="@this" render=":uploadClassicCarForm:conditions"/>
                        </p:selectOneMenu>
                    </td>
                    <td>
                        <p:datePicker styleClass="smallDate" inputStyleClass="smallDateInput" panelStyleClass="smallDatePanel" readonlyInput="true" id="restoredDate" view="month" value="#{c.restorationDate}" pattern="MMM yyyy" 
                                hideOnDateTimeSelect="true" yearNavigator="true" yearRange="#{sessionDataWrapper.sessionData.classicCarDto.getYears()}" placeholder="Month, Year" disabled="#{c.restored eq 'false' or c.restored eq null}">
                            <p:ajax event="dateSelect" process="@this" />
                        </p:datePicker>
                    </td>
                    <td>
                        <p:selectOneMenu class="tableDropdown" id="professionally" value="#{c.professionallyRestored}" disabled="#{c.restored eq 'false' or c.restored eq null}">
                            <f:selectItem itemLabel="Select" itemValue=""/>
                            <f:selectItem itemLabel="Yes" itemValue="true"/>
                            <f:selectItem itemLabel="No" itemValue="false"/>
                            <p:ajax event="change" process="@this" />
                        </p:selectOneMenu>
                    </td>
                    <td>
                        <p:inputNumber class="tableNumber" id="restorationCost" minValue="0" maxValue="999999999" value="#{c.restorationCost}" symbol="£ " emptyValue="focus" decimalPlaces="0" 
                            placeholder="£ " disabled="#{c.restored eq 'false' or c.restored eq null}">
                            <p:ajax event="change" />
                        </p:inputNumber>
                    </td>
                </tr>
            </ui:repeat>
            </tbody>
        </table>
</p:outputPanel>

【问题讨论】:

  • Primefaces 版本?您是否尝试过使用 p:ajax 更新最后三列?尝试查看此question,了解更多信息。
  • 你的后台bean是RequestScoped吗?
  • 请提供minimal reproducible example,其中包括:错误的简短描述以及导致错误的操作、相关的 xhtml 代码(选择输入)以及 bean 的相关代码段。如果您对如何提问有疑问,请查看其他示例:)
  • 我们使用的是 primefaces 8.0 版,后面的 bean 是 SessionScoped。谢谢,我已将此信息添加到主要问题中。
  • 是的,请删除一些东西..还有构图、表格、输出面板等......让它成为真正的minimal reproducible example

标签: ajax jsf primefaces jsf-2.2


【解决方案1】:

我注意到你的代码中有这个:

<p:selectOneMenu class="tableDropdown" id="restored" value="#{c.restored}">
    <f:selectItem itemLabel="Select" itemValue=""/>
    <f:selectItem itemLabel="Yes" itemValue="true"/>
    <f:selectItem itemLabel="No" itemValue="false"/>
    <f:ajax event="change" process="@this" render=":uploadClassicCarForm:conditions"/>
</p:selectOneMenu>

<f:ajax event="change" process="@this" render=":uploadClassicCarForm:conditions"/>

在几个方面存在“错误”。

  1. 最好在 PrimeFaces 组件中使用p:ajax
  2. 属性是p:ajax 和 f:ajax 的混合
    • f:ajax:没有process 属性,而是execute
    • p:ajax:没有render 属性,但有update

所以这似乎是一种混合。不确定它是否是(部分)原因,但错误永远不会少

【讨论】:

  • 谢谢,我刚刚更新为使用 p:ajax 和 update 属性。问题仍在发生,但略有不同。不仅“条件”值被重置为空,“恢复”值现在也将变为空。再次像以前一样,这只是第一次,一旦发生一次,在任何表行的会话期间再也不会发生。
  • 我们找到了一个可行的解决方案。根据上述评论,将所有更改为使用 p:ajax 不起作用,但是将所有更改为 f:ajax 解决了问题,现在它可以按预期工作。
  • 然后创建一个包含详细信息的答案...希望看到差异,并可能找出您的更改有效的原因
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-27
  • 2012-12-28
  • 2016-02-17
  • 2013-01-03
  • 2011-09-11
  • 2012-01-31
相关资源
最近更新 更多