У меня есть 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, те же коды работают нормально.
Кто-нибудь сталкивался с такой же проблемой? Как это решить?