我正在尝试创建一个表单,我希望在其中对各个字段进行即时 AJAX 验证,并使用 AJAX 处理整个表单
但是对于某些组件,我遇到了这种方法的问题。例如,来自 OpenFaces 的 <o:dropDownField/> 组件会导致脚本错误,当它被快速重新渲染多次时。
使用 JSF 1.2、RichFaces 3.3.3.Final 和 OpenFaces 2.0.r13,表单可能类似于:
<a4j:queue/>
<h:form>
<h:panelGroup id="myForm">
<f:facet name="aroundInvalidField">
<s:div style="border: 2px solid red"/>
</f:facet>
<h:messages/>
<h:panelGrid id="myGrid" columns="2">
<s:decorate id="dropDownFieldDecorator">
<o:dropDownField id="dropDownField"
value="#{controller.library}"
autoComplete="true">
<o:dropDownItem value="OpenFaces"/>
<o:dropDownItem value="RichFaces"/>
<a4j:support event="onchange"
ajaxSingle="true"
reRender="dropDownFieldDecorator"/>
</o:dropDownField>
</s:decorate>
<a4j:commandButton value="Save"
action="#{controller.save}"
reRender="myForm"/>
</h:panelGrid>
</h:panelGroup>
</h:form>
如果我在 dropDownField 的输入中写了一些东西(并将焦点留在那里),然后单击“保存”按钮,我将接连获得两个 AJAX 调用:
- 一个用于 dropDownField 上的更改事件,以及
- 一个用于“保存”按钮。
至少在 IE8 中,我很可能会收到一个脚本错误,指出“O$.Tables._initColumns: colTags.length(0) != colCount(1)”。
问题似乎源于这样一个事实,即 <o:dropDownField> 组件的 javascript 初始化通过将它们包装在 setTimeout() 中来“推迟”一个或多个步骤。
所以当richfaces AJAX 处理器认为它已经处理完第一个请求时,它会开始处理第二个请求。但是当推迟的步骤开始执行时,我现在将有两组dropDownField 初始化代码试图同时完成它们的工作——它们互相踩到对方的脚趾,我得到脚本错误......
有人对如何避免这个问题有任何建议吗?