Форма отправки в условно представленный компонент не обрабатывается
У меня есть специальный файл тегов с формой:
<h:form>
<h:commandButton value="click">
<f:ajax event="click" listener="#{bean[method]}" />
</h:commandButton>
</h:form>
Я условно отрисовываю его с помощью ajax, как показано ниже:
<h:panelGroup id="test">
<h:form>
<h:commandButton value="click">
<f:ajax event="click" listener="#{backingTest.updateFlag}" render=":test"/>
</h:commandButton>
</h:form>
<h:panelGroup rendered="#{backingTest.flag}">
<my:customtag bean="#{backingTest}" method="printMessage"/>
</h:panelGroup>
</h:panelGroup>
Это связанный компонент поддержки:
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
@ManagedBean
@RequestScoped
public class BackingTest {
private boolean flag = false;
public void printMessage() {
System.out.println("hello");
}
public void updateFlag() {
flag = true;
}
public boolean getFlag() {
return flag;
}
}
Когда я нажимаю первую кнопку команды, то updateFlag()
метод вызывается правильно, и вторая кнопка команды отображается правильно. Но когда я нажимаю вторую кнопку, она никогда не printMessage()
метод. В консоли JS веб-браузера и мониторе HTTP-трафика я вижу, что click
событие успешно запущено, и запрос XHR POST успешно отправляется.
Если я удалю rendered
атрибут, то все работает как положено.
Как это вызвано и как я могу решить это? Я использую Mojarra 2.1.25.
1 ответ
Ваша конкретная проблема вызвана двумя фактами:
- Когда JSF необходимо декодировать действие отправки формы, он также проверяет, отображается ли компонент или нет (как защита от взломанных / подделанных запросов).
- Bean-объекты запроса повторяются при каждом HTTP-запросе (ajax-запрос также считается одним запросом!).
В вашем конкретном случае rendered
состояние оценил false
в то время как JSF необходимо декодировать действие отправки формы и, следовательно, неотрисованные компоненты ввода / команды никогда не обрабатываются.
Помещение бина в область видимости должно исправить это. Ниже приведен пример JSF 2.x.
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
@ManagedBean
@ViewScoped
И ниже пример предполагает JSF 2.2+ с CDI:
import javax.inject.Named;
import javax.faces.view.ViewScoped;
@Named
@ViewScoped