0

データテーブルに何を表示するかを制御する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 に変更すると、同じコードが正常に機能しました。

誰も同じ問題に直面していますか?これを解決するには?

4

2 に答える 2

1

実際に更新されたcurrentEnvName値は

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

あなたのように設定する必要はありません...

そして、これらすべてのものの代わりに、ValueExpression管理されたプロパティを使用することをお勧めします。内部GCSelectionBeanに次を追加します。

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

currentEnvNamefrom envMenuBean オブジェクトにアクセスするよりも...

それで全部です ?

于 2012-10-22T06:58:46.253 に答える
0

これは、primefaces に問題があるようです。primefaces を primefaces-3.4-SNAPSHOT から primefaces-3.4.1 にアップグレードすると、問題は解決します。

于 2012-10-23T02:46:23.887 に答える