我有一个 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 时,相同的代码运行良好。
有没有人遇到过同样的问题?如何解决这个问题?