JSF 中的异步验证器
Asynchronous validators in JSF
我有一个包含编辑框和按钮的简单表单:
<h:form id="addForm">
<h:outputLabel value="Add item here" /><br />
<p><h:inputText id="itemInput" value="#{myController.itemToAdd}" validator="myValidator" />
<h:message for="itemInput" /></p>
<h:commandButton value="Add" action="#{myController.addItemToList}">
<f:ajax execute="@form" render="@form :addedItems" />
</h:commandButton>
</h:form>
当用户点击按钮时,一些基本的验证完成,如果一切正常,项目被添加到数据 table:
<h:panelGrid id="addedItems">
<h:dataTable value="#{myController.itemMap.entrySet()}" var="itemMapEntry" >
<h:column>
<f:facet name="header">
<h:outputText value="Items" />
</f:facet>
<h:commandButton value="Remove/Modify" action="#{myController.removeItemFromList(itemMapEntry.getKey())}">
<f:ajax render=":addedItems :addForm" />
</h:commandButton>
<h:outputText value="#{itemMapEntry.getKey()}" />
</h:column>
<h:column>
<f:facet name="action">
<h:outputText value="" />
</f:facet>
<h:outputText value="#{itemMapEntry.getValue().toString()}" id="itemValidationStatus" />
</h:column>
</h:dataTable>
</h:panelGrid>
现在,我想要实现的是,当用户输入一个项目时,首先进行初步验证,如果验证成功,则将项目添加到列表一起显示的 table具有验证状态(例如验证、无效、有效)。当项目被添加到 table 时,另一个更耗时的验证开始,当验证完成时 table 中的 itemValidationStatus 被更新。我不想在耗时的验证期间阻止用户。相反,我想允许用户在验证已添加的项目时添加更多项目。
我看到了三种解决方法:
注册某种会对对象做出反应的 JS 观察器是
正在托管 bean 中更新
从托管 bean 触发呈现
可能产生一个验证线程,在完成后,
触发渲染
有一些方法可以通过 JS 异步启动验证和
注册一个将触发渲染的回调函数
或者直接更新值
问题是我在网上找不到任何可以为我指明正确方向的信息。我正在尝试使用纯 JSF(没有 Prime Faces 或类似工具)来解决这个问题。
编辑:
有人建议我提出另一个可能重复的问题(JSF,使用 ajax 定期刷新组件?)。我不是在寻找一种定期轮询的解决方案,而是在基础数据发生变化时进行更新。而且它只会更改一次,因此显而易见的解决方案是事件侦听器或类似的解决方案。当然,这也可以通过定期民意调查来解决,但对于我所追求的来说,这似乎是非常低的水平。
现在我通过以下更改解决了它(受此 JQuery 相关问题 How to trigger JSF render from jQuery 启发):
我在表格的<f:ajax>
标签中添加了onevent="validateItemList"
:
<h:form id="addForm">
<h:outputLabel value="Add item here" /><br />
<p><h:inputText id="itemInput" value="#{myController.itemToAdd}" validator="myValidator" />
<h:message for="itemInput" /></p>
<h:commandButton value="Add" action="#{myController.addItemToList}">
<f:ajax execute="@form" onevent="validateItemList" render="@form :addedItems" />
</h:commandButton>
</h:form>
我添加了一个带有隐藏按钮的隐藏表单,该按钮会触发耗时的验证并重新呈现 table:
<h:form id="hiddenForm">
<h:commandButton value="" action="#{myController.validateItemMap}" id="validatorButton" style="display:none">
<f:ajax execute="@form" render=":addedItems" />
</h:commandButton>
</h:form>
我添加了回调JS函数,"pushes"隐藏按钮:
<script type="text/javascript">
function validateItemList(data){
if(data.status == "success"){
document.getElementById("hiddenForm:validatorButton").click();
}
}
</script>
我有一个包含编辑框和按钮的简单表单:
<h:form id="addForm">
<h:outputLabel value="Add item here" /><br />
<p><h:inputText id="itemInput" value="#{myController.itemToAdd}" validator="myValidator" />
<h:message for="itemInput" /></p>
<h:commandButton value="Add" action="#{myController.addItemToList}">
<f:ajax execute="@form" render="@form :addedItems" />
</h:commandButton>
</h:form>
当用户点击按钮时,一些基本的验证完成,如果一切正常,项目被添加到数据 table:
<h:panelGrid id="addedItems">
<h:dataTable value="#{myController.itemMap.entrySet()}" var="itemMapEntry" >
<h:column>
<f:facet name="header">
<h:outputText value="Items" />
</f:facet>
<h:commandButton value="Remove/Modify" action="#{myController.removeItemFromList(itemMapEntry.getKey())}">
<f:ajax render=":addedItems :addForm" />
</h:commandButton>
<h:outputText value="#{itemMapEntry.getKey()}" />
</h:column>
<h:column>
<f:facet name="action">
<h:outputText value="" />
</f:facet>
<h:outputText value="#{itemMapEntry.getValue().toString()}" id="itemValidationStatus" />
</h:column>
</h:dataTable>
</h:panelGrid>
现在,我想要实现的是,当用户输入一个项目时,首先进行初步验证,如果验证成功,则将项目添加到列表一起显示的 table具有验证状态(例如验证、无效、有效)。当项目被添加到 table 时,另一个更耗时的验证开始,当验证完成时 table 中的 itemValidationStatus 被更新。我不想在耗时的验证期间阻止用户。相反,我想允许用户在验证已添加的项目时添加更多项目。
我看到了三种解决方法:
注册某种会对对象做出反应的 JS 观察器是 正在托管 bean 中更新
从托管 bean 触发呈现 可能产生一个验证线程,在完成后, 触发渲染
有一些方法可以通过 JS 异步启动验证和 注册一个将触发渲染的回调函数 或者直接更新值
问题是我在网上找不到任何可以为我指明正确方向的信息。我正在尝试使用纯 JSF(没有 Prime Faces 或类似工具)来解决这个问题。
编辑:
有人建议我提出另一个可能重复的问题(JSF,使用 ajax 定期刷新组件?)。我不是在寻找一种定期轮询的解决方案,而是在基础数据发生变化时进行更新。而且它只会更改一次,因此显而易见的解决方案是事件侦听器或类似的解决方案。当然,这也可以通过定期民意调查来解决,但对于我所追求的来说,这似乎是非常低的水平。
现在我通过以下更改解决了它(受此 JQuery 相关问题 How to trigger JSF render from jQuery 启发):
我在表格的
<f:ajax>
标签中添加了onevent="validateItemList"
:<h:form id="addForm"> <h:outputLabel value="Add item here" /><br /> <p><h:inputText id="itemInput" value="#{myController.itemToAdd}" validator="myValidator" /> <h:message for="itemInput" /></p> <h:commandButton value="Add" action="#{myController.addItemToList}"> <f:ajax execute="@form" onevent="validateItemList" render="@form :addedItems" /> </h:commandButton> </h:form>
我添加了一个带有隐藏按钮的隐藏表单,该按钮会触发耗时的验证并重新呈现 table:
<h:form id="hiddenForm"> <h:commandButton value="" action="#{myController.validateItemMap}" id="validatorButton" style="display:none"> <f:ajax execute="@form" render=":addedItems" /> </h:commandButton> </h:form>
我添加了回调JS函数,"pushes"隐藏按钮:
<script type="text/javascript"> function validateItemList(data){ if(data.status == "success"){ document.getElementById("hiddenForm:validatorButton").click(); } } </script>