这个 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 选择的默认值),则表单提交正常。如果我将类型切换ONE
为此正确呈现“首先选择模板”文本而不是提交控件。通过选择另一种类型来恢复提交按钮会重新生成<input>
BUT,而没有onclick
第一次呈现表单时存在的处理程序。
现在单击<h:commandButton>
向服务器发送请求但不会触发相关操作。但是,它现在恢复了 onclick 处理程序,并且第二次单击会触发正确的提交。
我不知道为什么会这样。有什么建议么?
编辑:将rendered
属性移动到按钮会导致相同的行为(即使它确实有效,原始面板也包含更多共享相同条件的控件,因此它们确实起到了作用)
EDIT2:我刚刚测试过,只需重新添加在onclick
提交按钮上呈现的“丢失”处理程序(通过萤火虫)即可使操作按预期工作。我开始怀疑 Richfaces 和该项目中也包含的 trinidad 库之间的不良交互(但未在此页面上使用)。