Форма отправки в условно представленный компонент не обрабатывается

У меня есть специальный файл тегов с формой:

<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 ответ

Решение

Ваша конкретная проблема вызвана двумя фактами:

  1. Когда JSF необходимо декодировать действие отправки формы, он также проверяет, отображается ли компонент или нет (как защита от взломанных / подделанных запросов).
  2. 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

Смотрите также:

Другие вопросы по тегам