JSF部分屏幕更新处理完整的组件树

M. *_*num 12 ajax primefaces jsf-2

我需要一些JSF/PrimeFaces(3.5)建议.

我们有一个动态表单,表单可以由表单构建器配置,并且支持bean是一个美化的,HashMap带有一些额外的getter和setter,如(getValueAsDate/ setValueAsDate).

我们的一种字段类型允许输入数字,当离开该字段时,请求附加信息并更新表单的一部分.这似乎很好地工作.

<h:panelGroup id="clientInfo" layout="block" rendered="#{field.type == 'CLIENTINFO'}">
    <h:outputLabel for="inputClientId">#{field.label}</h:outputLabel>
    <p:inputText id="inputClientId" maxlength="9" value="#{handler.property(field.id).value}">
        <p:ajax listener="#{handler.fetchClientDetails(field.id)}" partialSubmit="true" process="@this" update="@parent,:mainform:msgs"
    </p:inputText>
    <!-- Additional output text elements to display the name, address etc. -->
</h:panelGroup>
Run Code Online (Sandbox Code Playgroud)

最近我们添加了一个允许java.util.Date使用PrimeFaces日期选择器组件输入的字段.添加此字段类型后,部分更新停止工作.

<h:panelGroup id="date" layout="block" rendered="#{field.type == 'DATE'}">
    <h:outputLabel for="inputDate">#{field.label}</h:outputLabel>
    <p:calendar id="inputDate" value="#{handler.property(field.id).valueAsDate}" pattern="dd-MM-yyyy" maxlength="10">
        <f:convertDateTime pattern="dd-MM-yyyy" />
    </p:calendar>
</h:panelGroup>
Run Code Online (Sandbox Code Playgroud)

当检查来自服务器的部分结果时,我们得到类似下面的内容(其中12345是在上面的字段中输入的clientId).

<partial-response>
    <error>
        <error-name>class java.text.ParseException</error-name>
        <error-message><![CDATA[Unparseable date: "12345"]]></error-message>
    </error>
</partial-response>
Run Code Online (Sandbox Code Playgroud)

问题基本上是为什么它甚至getValueAsDate为一个不是a的字段调用方法,Date或者什么时候屏幕上甚至没有日期字段类型?这可能是我对JSF生命周期缺失(或误解)或JSF/PrimeFaces中部分更新如何工作的原因.

更新#1:

刚刚在另一个调试会话中注意到,这不仅发生在部分更新中,而且在最初渲染屏幕时已经发生.似乎所有EL表达式都是一直被评估的,这也会导致我的后备对象中的其他属性(当请求一个属性并且它不存在时,它将使用该值创建null).

更新#2:

呈现已配置字段的代码使用ui:repeaten条件ui:fragment(也尝试过h:panelGroup)来呈现已配置字段的特定输入元素.

<ui:repeat value=#{handler.formFields} var="field">
    <ui:fragment rendered="field.type == 'DATE'>
        <!-- Specific fragment for date field -->
    </ui:fragment>
    <ui:fragment rendered="field.type == 'TEXT'>
    </ui:fragment>
    <ui:fragment rendered="field.type == 'REGEXP'>
    </ui:fragment>
    <ui:fragment rendered="field.type == 'CLIENT'>
    </ui:fragment>
</ui:repeat>
Run Code Online (Sandbox Code Playgroud)

尝试了2 h:panelGroupui:fragments2的组合.

Bal*_*usC 8

这被认为是一个Mojarra特定的<ui:repeat>bug,报告为问题3215,在2.2.7中修复,并按照问题3221在2.1.29中向后移植.简单地说,问题可归结为在保存自己的状态时<ui:repeat>不尊重其EditableValueHolder子女的状态,因此基本上表现得好像rendered这些孩子的属性在国家储蓄期间从未受到尊重.在以下相关问答中充实了其中一个后果:在ui:repeat中有条件地呈现的子类上的PropertyNotFoundException.

鉴于你使用的是Mojarra 2.1.x,最好的办法是升级到至少2.1.29.如果你的环境允许它(Servlet 3.0等),也应该可以升级到最新的2.2.x.

替代品将取代MyFaces的Mojarra,或替换<ui:repeat><ui:fragment><c:forEach><c:if>.