如何在 JSF 中使用转换器和 ajax 更新字段

How to update a field using a converter and ajax in JSF

如果值当前为空或 null,我基本上会显示两个输入字段。如果不是,我会显示一个 outputText。这两个值是存储在 Long 对象中的货币值,我使用转换器来正确显示数据(我不能使用 PrimeFaces 的 inputNumber,因为我使用的是 PrimeFaces 5.3)。我的问题如下:

<c:set var="edtVal1" value="#{bean.val1 ne null and bean.val1 ne 0}" scope="request" />
<c:set var="edtVal2" value="#{bean.val2 ne null and bean.val2 ne 0}" scope="request" />

<p:panelGrid>
    <p:row>
        <p:column colspan="2">
            <p:messages id="mainMessages" globalOnly="false" autoUpdate="true" showDetail="true" />
        </p:column>
    </p:row>
    <!-- [...] -->

    <p:row>
        <p:column styleClass="col-quarter col-label2">
            <h:outputText value="value 1" />
        </p:column>
        <p:column styleClass="col-quarter col-value2" rendered="#{edtVal1}">
            <h:outputText id="val1Output" value="#{bean.val1}" converter="myConverter" />
        </p:column>
        <p:column styleClass="col-quarter" rendered="#{not edtVal1}">
            <p:inputText id="val1Input" value="#{bean.val1}" converter="myConverter">
                <p:ajax update="mainMessages val1Input" event="change" />
            </p:inputText>
        </p:column>
    </p:row>
    <p:row>
        <p:column styleClass="col-quarter col-label2">
            <h:outputText value="value 2" />
        </p:column>
        <p:column styleClass="col-quarter col-value2" rendered="#{edtVal2}">
            <h:outputText id="val1Output" value="#{bean.val2}" converter="myConverter" />
        </p:column>
        <p:column styleClass="col-quarter" rendered="#{not edtVal2}">
            <p:inputText id="val1Input" value="#{bean.val2}" converter="myConverter">
                <p:ajax update="mainMessages val1Input" event="change" />
            </p:inputText>
        </p:column>
    </p:row>
</p:panelGrid>

当我这样写时,显示了转换器抛出的消息,但更新了 none 个字段。但是,如果我对两个 input/output 选项使用相同的布尔变量(将第一个数据行的 rendered 属性中使用的变量更改为在两者中使用 edtVal2),如下所示:

<p:row>
    <p:column styleClass="col-quarter col-label2">
        <h:outputText value="value 1" />
    </p:column>
    <p:column styleClass="col-quarter col-value2" rendered="#{edtVal1}">
        <h:outputText id="val1Output" value="#{bean.val1}" converter="myConverter" />
    </p:column>
    <p:column styleClass="col-quarter" rendered="#{not edtVal1}">
        <p:inputText id="val1Input" value="#{bean.val1}" converter="myConverter">
            <p:ajax update="mainMessages val1Input" event="change" />
        </p:inputText>
    </p:column>
</p:row>

第一个字段更新成功,第二个仍然不行。

使用转换器显示格式化数据是我已经完成的一种解决方法,它按预期工作,我使用与以前相同的转换器。但是这次,我不明白为什么它不起作用。

转换器对于重现问题很重要,但任何自定义转换器似乎都可以完成这项工作。

在此 post 上仍然欢迎任何其他解决方案,但我设法找到了一个可行的解决方案:

当我将 rendered 属性更改为常量字符串时,问题不复存在。所以我觉得问题出在对<c:set>.

的误解

我的解决方案是使用 bean 作为控制器。我将变量从 xhtml 文件更改为控制器中的属性,现在一切正常。所以我从我的 xhtml 中删除了所有 <c:set> 并现在在该页面上使用适当的 MVC 模式。


注:
对于那些不知道什么是 MVC 的人:它是一种简洁的架构模式,可以清楚地划分用户界面和操作数据。了解更多 on wikipedia