p:inputText 与 p:ajax 调用 f:viewParam 转换器

p:inputText with p:ajax calls f:viewParam Converter

我们确实有一个小页面,它使用 viewParam 将给定的 Id 转换为具体对象。此转换器在离开(模糊)已验证的 inputText 字段时被调用。为什么?我可以重做这个,以便每次都不会调用转换器吗?

这很烦人,因为转换器调用了 BackingBean 中相应对象的 set-method,如果第一次调用页面创建此对象,则此 bean 为 null。

<f:metadata>
    <f:viewParam name="id" value="#{bean.object}"
                 converter="#{objectConverter}"
                 converterMessage="#{msgs['converter.msg.object']}"/>
    <f:viewAction action="#{bean.init}"/>
</f:metadata>

<p:inputText id="text" value="#{cc.attrs.value}"
             styleClass="inputTextValidated"
             required="#{cc.attrs.required}"
             requiredMessage="#{cc.attrs.requiredmessage}"
             label="text" validatorMessage="#{cc.attrs.msg}" title="#cc.attrs.title}"
             readonly="#{cc.attrs.readOnly}">
            <cc:insertChildren/>
            <p:ajax update="msg_text" event="blur"/>
</p:inputText>
<p>
  <p:message id="msg_text" for="text" display="msg"/>
</p>

如果我们不使用转换器而只使用 viewAction 将 Id 转换为相应的对象(或者创建一个新对象,如果适用),一切都很好。这是这个问题的 only/correct 解决方案吗?

我们确实将 primefaces 6.1 与 CDI 一起使用。转换器是实现转换器接口的 @Named 和 @ApplicationScoped bean。

在输入文本字段周围使用 p:fragment 也没有帮助。

这就是 JSF 工作方式的本质。如果你不想这样做,我建议你查看 OminFaces ViewParam:http://showcase.omnifaces.org/components/viewParam

来自他们的文档:

Stateless mode to avoid unnecessary conversion, validation and model updating on postbacks The standard UIViewParameter implementation calls the model setter again after postback. This is not always desired when being bound to a view scoped bean and can lead to performance problems when combined with an expensive converter. To solve this, this component by default stores the submitted value as a component property instead of in the model (and thus in the view state in case the binding is to a view scoped bean).

The standard UIViewParameter implementation calls the converter and validators again on postbacks. This is not always desired when you have e.g. a required="true", but the parameter is not retained on form submit. You would need to retain it on every single command link/button by . To solve this, this component doesn't call the converter and validators again on postbacks.