Jsf 如果h:commandButton的父级是动态呈现的,为什么它不能提交表单?

Jsf 如果h:commandButton的父级是动态呈现的,为什么它不能提交表单?,jsf,richfaces,seam,jsf-1.2,Jsf,Richfaces,Seam,Jsf 1.2,这个JSF1代码让我困惑了好几个小时。基本设置是此页面显示的Seam2: <h:form encType="multipart/form-data"> <rich:dataTable value="#{results}"> ... </rich:dataTable> <h:selectOneMenu value="#{contact.type}"> <s:selectItems value="#{contactT

这个JSF1代码让我困惑了好几个小时。基本设置是此页面显示的Seam2:

<h:form encType="multipart/form-data">
  <rich:dataTable value="#{results}">
    ...
  </rich:dataTable>

  <h:selectOneMenu value="#{contact.type}">
    <s:selectItems value="#{contactTypes}" var="t" label="#{t.label}" />
    <s:convertEntity />
    <a4j:support event="onchange" reRender="submitControls" />
  </h:selectOneMenu>

  <h:selectOneMenu value="#{template}">
    <s:selectItems value="#{allTemplates}" var="t" label="#{t.label}" />
    <s:convertEntity />
    <a4j:support event="onchange" reRender="submitControls" />
  </h:selectOneMenu>

  <a4j:outputPanel id="submitControls" layout="block">
    <a4j:outputPanel rendered="#{null != results and results.size gt 0 and ('ONE' == contact.type.label or template != null)}">
      <h:commandButton value="submit" action="#{manager.generate}" />
    </a4j:outputPanel>

    <h:outputText value="Search first" rendered="#{results == null or results.size == 0}" />
    <h:outputText value="Select template first" rendered="#{'ONE' == contact.type.label and template == null}" />
  </a4j:outputPanel>
</h:form>
显然,原来的页面有点大。让我抓狂的是,如果我不更改contact.type,请将其保留为支持bean选择的默认值,表单将很好地提交。如果我将类型切换为一个,这将正确呈现选择模板第一个文本,而不是提交控件。通过选择另一个类型来恢复submit按钮,将重新生成表单,但没有第一次呈现表单时的onclick处理程序

现在,单击将向服务器发送请求,但不会触发相关操作。但是,它现在恢复onclick处理程序,第二次单击将触发正确的提交

我不知道为什么会这样。有什么建议吗

编辑:将渲染属性移动到按钮会导致相同的行为,即使它确实起作用,原始面板包含更多共享相同条件的控件,因此它们确实起到了作用


EDIT2:我刚刚测试过,只要通过firebug重新添加丢失的onclick处理程序,该处理程序就会在submit按钮上呈现,从而使操作按预期工作。我开始怀疑richfaces和trinidad LIB之间的交互不好,它们也包含在这个项目中,但没有在这个页面上使用。

我认为,对于呈现属性和其中的任何内容,您必须注意在初始请求和提交时对它的评估是相同的。它可能会在渲染阶段之前更改,但如果在应用程序调用期间它不相同,则很可能会忽略该操作,如果在此阶段按钮不会被渲染


据我记忆所及,这种情况主要发生在渲染表达式使用实体属性之类的东西时,该属性将在应用请求值阶段更改

这是一种防止篡改/黑客请求的保护措施。否则,黑客将能够通过相应地编辑发送的HTTP请求参数来调用不允许调用的操作,例如,由于缺少管理角色命令按钮,将调用未呈现的

您需要确保在处理表单提交的HTTP请求期间准备相同的模型托管bean实例,所有属性负责保存呈现属性后面的条件,就像在显示表单的HTTP请求期间一样。在JSF2中,通过将bean放在视图范围而不是请求范围中,这是很容易实现的。只要您与同一视图交互,视图作用域就会存在。在JSF1中,您需要获取一个第三方框架标记,如Tomahawk或RichFaces
您如何验证请求是否已发送到服务器?萤火虫?尝试将条件渲染放在命令按钮本身上,与父outputPanel相反,在这种情况下,即使输出面板也会变为unnecessary@kolossus是的,在firebug的帮助下,我看到了服务器上的帖子。响应包含带有onclick处理程序的按钮,实际提交可能会发生。事实是,变量results、contact和template从两个不同的bean结果中作为@DataModel从一个额外的bean中导出。但是,持有字段的bean具有seam的对话范围。我怀疑这不包括没有发布会话id的AJAX请求,对吗?这仍然不能解释为什么submit按钮丢失了它的onclick处理程序……忘记说:我已经为这里正在使用的bean添加了一些,但是问题仍然存在。
<a4j:keepAlive beanName="results" />