データテーブルに何を表示するかを制御する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>
正しい新しい値を表示できます。
これは、ajax変更イベントを処理する前に、myfacesが最初にテーブルをレンダリングすると信じています。JSF2.0 の実装を myfaces から Glassfish に変更すると、同じコードが正常に機能しました。
誰も同じ問題に直面していますか?これを解決するには?