Apache myfaces отображает данные перед обработкой события ajax

У меня есть selectOneMenu, который контролирует, что должно отображаться в таблице данных. Код такой, как показано ниже (я удалил все лишнее):

<ui:composition template="/WEB-INF/templates/BasicTemplate.xhtml">
  <ui:define name="content">
    <br />
    <h:form id="menuform">

      <p:selectOneMenu value="#{envMenuBean.currentEnvName}">
        <f:selectItems value="#{envMenuBean.envs}" var="env" itemLabel="#{env.name}" itemValue="#{env.name}" />
        <p:ajax event="change" update="currentEnvoutput,contentpanel" listener="#{envMenuBean.envChange}" />
      </p:selectOneMenu>

      <h:outputLabel value="Current Selection: " />
      <h:outputText id="currentEnvoutput" style="font-weight:bold" value="#{envMenuBean.currentEnvName}"></h:outputText>

      <br />
      <p:panel id="contentpanel">
        <div id="contentdiv">
          <p:dataTable id="gcfiletable" var="row" value="#{gCSelectionBean.dataTableDTO.serverListRows}">
            <p:column>
              <f:facet name="header">
                <h:outputText value="Server Names" />
              </f:facet>
              <h:outputText value="#{row.serverName}" />
            </p:column>
            <p:columns value="#{gCSelectionBean.dataTableDTO.machineNamesList}" var="columnName" columnIndexVar="colIndex">
              <f:facet name="header">  
                #{columnName}  
              </f:facet>
            </p:columns>
          </p:dataTable>
        </div>
      </p:panel>

    </h:form>
  </ui:define>
</ui:composition>

Код envMenuBean.envChange очень прост:

@ManagedBean
@SessionScoped
public class EnvMenuBean {
  private String currentEnvName;    

  public void envChange(AjaxBehaviorEvent event) {
    String newValue = (String)((UIOutput)event.getSource()).getValue();
    currentEnvName = newValue;
  }
}

Контент с данными создается в классе gCSelectionBean:

@ManagedBean
@SessionScoped
public class GCSelectionBean {
  private GCInstanceDataTableDTO dataTableDTO;  
  String currentEnvName;

  public GCInstanceDataTableDTO getDataTableDTO() {
    FacesContext fc = FacesContext.getCurrentInstance();
    Application app = fc.getApplication();
    ExpressionFactory exp = app.getExpressionFactory();

    ValueExpression currEnvNameMenuBeanEL = exp.createValueExpression(fc.getELContext(), "#{envMenuBean.currentEnvName}", String.class);
    String currEnvNameMenuBean = (String) currEnvNameMenuBeanEL.getValue(fc.getELContext());    

    ApplicationConfigs gcReportConfigs = GetAppConfigs.getInstance().getAppConfigs();
    for (Environment env : gcReportConfigs.getEnvs()) {
      if (env.getName().equalsIgnoreCase(currEnvNameMenuBean)) {         
        dataTableDTO = new GCInstanceDataTableDTO(env);
        currentEnvName = currEnvNameMenuBean;
        break;
      }
    }

    return dataTableDTO;
  }  
}

Однако код

    ValueExpression currEnvNameMenuBeanEL = exp.createValueExpression(fc.getELContext(), "#{envMenuBean.currentEnvName}", String.class);
    String currEnvNameMenuBean = (String) currEnvNameMenuBeanEL.getValue(fc.getELContext());    

дает мне старое значение selectOneMenu перед изменением, что делает мою таблицу данных по-прежнему отображающей старые значения таблицы. Но

<h:outputText id="currentEnvoutput" style="font-weight:bold" value="#{envMenuBean.currentEnvName}"></h:outputText>

может показать правильное новое значение.

Это заставляет меня поверить, что myfaces сначала отображает таблицу перед обработкой события изменения ajax. Когда я меняю реализацию JSF2.0 с myfaces на Glassfish, те же коды работают нормально.

Кто-нибудь сталкивался с такой же проблемой? Как это решить?


person flyasfish    schedule 22.10.2012    source источник


Ответы (2)


Фактически обновленное значение currentEnvName должно присутствовать в

public void envChange(AjaxBehaviorEvent event) {
    System.out.println(currentEnvName );
}

Вам не нужно настраивать его так, как вы...

И вместо всех этих ValueExpression вещей вам лучше использовать управляемые свойства Внутри вашего GCSelectionBean добавьте следующее:

@ManagedProperty(value = "#{envMenuBean }")
private EnvMenuBean envMenuBean ; //add getter and setter

чем получить доступ к currentEnvName из объекта envMenuBean...

Это все ?

person Daniel    schedule 22.10.2012
comment
Я пробовал ваши предложения, но не повезло. Поведение такое же. Только после обновления таблица покажет новые значения. Есть ли способ принудительно обновить после загрузки страницы? - person flyasfish; 23.10.2012

Кажется, это проблема с простыми лицами, после обновления простых лиц с простых лиц-3.4-SNAPSHOT до простых лиц-3.4.1 проблема решена.

person flyasfish    schedule 23.10.2012