Apache myfaces在处理ajax事件之前呈现数据表

时间:2012-10-22 05:37:52

标签: ajax jsf datatable myfaces selectonemenu

我有一个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时,相同的代码工作正常。

有没有人遇到同样的问题?如何解决这个问题?

2 个答案:

答案 0 :(得分:1)

实际更新的currentEnvName值应该出现在

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

你不必像你那样设置它......

而不是所有这些ValueExpression内容,您最好使用托管属性 在GCSelectionBean内添加以下内容:

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

从envMenuBean obejct ...

访问currentEnvName

这就是全部?

答案 1 :(得分:0)

这似乎与primefaces有关,在将primefaces-3.4-SNAPSHOT的primefaces升级到primefaces-3.4.1之后,问题得到了解决。