Это будет сложно. Из-за спецификации JSF 790 , всякий раз, когда вы повторно визуализируете некоторый контент, содержащий другой <h:form>
, используя <f:ajax>
, его состояние просмотра будет потеряно. Чтобы решить эту проблему, вам нужно будет ссылаться на полный идентификатор клиента другой <h:form>
внутри <f:ajax>
вместо некоторого содержащего компонента. Но у вас есть несколько форм внутри <h:dataTable>
, на которые нельзя ссылаться по абсолютному идентификатору клиента.
Вам нужно изменить код, чтобы поставить <h:form>
за пределы <h:dataTable>
и изменить <f:ajax>
на execute
только необходимые компоненты.
<h:form id="invoiceDataForm">
<h:dataTable id="invoiceData" value="#{attributes.priceAttributes}" var="loop">
<h:column>
<ui:param name="service" value="service#{loop}" />
<ui:param name="description" value="description#{loop}" />
<ui:param name="price" value="price#{loop}" />
<h:selectOneMenu id="selectMenu" value="#{invoiceBean[service]}">
<f:ajax execute="selectMenu,description,price" listener="#{invoiceServiceListener.procesServiceValueChange}" render="@form" />
<f:attribute name="row" value="#{loop}" />
<f:selectItems value="#{invoiceBean.services}" />
</h:selectOneMenu>
<h:inputText id="description" value="#{invoiceBean[description]}" />
<h:inputText id="price" value="#{invoiceBean[price]}" />
<h:outputText value="#{loop}" />
</h:column>
</h:dataTable>
</h:panelGroup>
, а затем ссылаться на него в первой форме следующим образом:
<f:ajax execute="clientSelect" listener="#{invoiceServiceListener.processClientValueChange}" render=":invoiceDataForm" />
Обратите внимание, что некоторые библиотеки компонентов, такие как PrimeFaces, уже обошли / решили эту проблему в специальном движке ajax библиотеки компонентов. Поэтому, если может случиться так, что вы уже используете PrimeFaces, вы также можете заменить <f:ajax>
первой формы на <p:ajax>
.
Не связанный с конкретной проблемой, <f:attribute name="row" value="#{loop}" />
может не выполнять то, что вы ожидаете. Он установит null
, потому что теги <f:xxx>
выполняются во время построения представления, а не во время отображения времени рендеринга. #{loop}
недоступен во время просмотра. Но это тема для другого вопроса:)