Отправка формы в условно отображаемом компоненте не обрабатывается

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

<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, то все будет работать как положено.

Чем это вызвано и как я могу это решить? Я использую Мохарру 2.1.25.


person user2775499    schedule 13.09.2013    source источник


Ответы (1)


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

  1. Когда JSF необходимо декодировать действие отправки формы или отправленное входное значение, он также проверяет, отображается ли компонент или нет (для защиты от взломанных/подделанных запросов).
  2. Bean-компоненты с областью запроса воссоздаются при каждом HTTP-запросе (запрос ajax также считается одним запросом!).

В вашем конкретном случае условие rendered оценило false, в то время как JSF необходимо декодировать действие отправки формы, и поэтому неотображенные компоненты ввода/команды никогда не обрабатываются.

Помещение bean-компонента в область видимости должно исправить это. В приведенном ниже примере предполагается 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

Или, если техническое требование состоит в том, чтобы сохранить компонент в области запроса, то перенесите условие за атрибутом rendered в <o:inputHidden>. Отредактируйте свой фрагмент, чтобы включить его в <h:form>.

<o:inputHidden value="#{backingTest.flag}" />

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

person BalusC    schedule 13.09.2013
comment
У меня аналогичная проблема. Есть ли обходной путь, с помощью которого вы могли бы найти решение с помощью bean-компонента с областью запроса? Как и в моем случае, веб-приложение уже огромно, и компонент должен иметь область запроса по нескольким другим причинам. - person 01000001; 24.05.2019