Мне нужен совет JSF/PrimeFaces (3.5).
У нас есть динамическая форма, форма может быть сконфигурирована конструктором формы, а поддержка bean - это прославленная HashMap
с некоторыми дополнительными геттерами и сеттерами, такими как (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>
Недавно мы добавили поле, которое позволило ввести a 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>
При проверке частичного результата с сервера мы получили что-то вроде следующего (где 12345 - clientId, введенное в поле выше).
<partial-response>
<error>
<error-name>class java.text.ParseException</error-name>
<error-message><![CDATA[Unparseable date: "12345"]]></error-message>
</error>
</partial-response>
Вопрос в том, почему он даже вызывает метод getValueAsDate
для поля, не являющегося Date
, или когда на экране даже нет типа поля даты? Вероятно, это то, что мне не хватает (или недоразумение) о жизненном цикле JSF или о том, как частичные обновления работают в JSF/PrimeFaces.
Обновление # 1:
Только что заметил в другом сеансе отладки, что это происходит не только для частичного обновления, но уже при первоначальном рендеринге экрана. Кажется, что все EL-выражения все время оцениваются, это также приводит к дополнительным свойствам в моем объекте backing (когда запрашивается свойство и оно не существует, оно создается со значением null
).
Обновление # 2:
Код для отображения сконфигурированных полей использует ui:repeat
en conditional 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>
Пробовал как h:panelGroup
, так и ui:fragments
комбинации 2.