Ajax调用从JSF页面上的bean中移除值。

问题描述 投票:0回答:1

第一次在stack overflow上发帖,所以如果我在提问时没有达到预期的标准,请原谅。

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

然而我们发现,当用户从 "条件 "中选择他们的选项,然后在 "restored "中选择 "是 "时,最后3列将正确地被启用,但在 "条件 "中输入的值被删除,并恢复为空。

添加日志到bean(它有通用的gettersetter方法),我可以看到这个值最初是被设置的,但在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>

ajax jsf primefaces jsf-2.2
1个回答
0
投票

我注意到你的代码里有这个。

<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. 最好是用一个 p:ajax 在PrimeFaces组件内
  2. 这些属性是混合的 p:ajax 和f:ajax
    • f:ajax:没有 process 赠与 execute
    • p:ajax无:无 render 的属性,而是一个 update

所以,这似乎是一种混合。不知道是否是(部分)原因,但错的不轻。

© www.soinside.com 2019 - 2024. All rights reserved.