我的输入字段有一个<f:ajax>
对象附加,使验证通过按TAB键成为可能:
<h:inputText id="input2" value="#{bean.property}">
<f:validator validatorId="customValidator" />
<f:ajax execute="@form" render="@this" />
</h:inputText>
如果有任何验证错误,它们将通过类似于<h:messages>
的自定义组件显示,并且输入框将通过自定义PhaseListener
进行样式设置。
我已经实现了一个自定义Faces Validator来跳过验证:
public class CustomValidator {
public void validate(FacesContext context, UIComponent component,
Object value) throws ValidatorException {
if (skipValidation(context)) {
return;
}
//Validation code goes here
}
这让我可以根据某些条件跳过bean验证,例如切换到另一个编辑器视图并将(可能错误的)数据保存在后台bean中。
现在,我的问题发生在刷新当前页面时(通过按F5,在导航栏中点击相同的链接或类似的)。备份中明显错误的数据按预期正确显示,但也应将其标记为无效。因此,我需要一种方法在每次页面加载时调用验证(目前它仅通过<f:ajax>
对象调用)。
我试着摆弄这样的东西
<f:ajax event="load" execute="editform" render="editform"/>
附在<h:body>
上。这是有效的,但网站被绘制了两次-我真的不关心是否有邪恶的闪烁,因为页面首先被绘制,然后被验证& &;通过ajax请求更新。
不要使用@SessionScoped
bean来返回页面;这是JSF设计的味道(如果有的话)
使用preRenderView
事件触发(或检查)您在页面加载时选择的任何验证逻辑。作为开头:
<f:event type="preRenderView" listener="#{bean.validate}" rendered="#{facesContext.postBack}" />
-
<f:event/>
标签在页面上注册一个事件监听器。 -
type="preRenderView"
属性规定事件应该在页面加载之前执行 -
rendered="#{facesContext.postBack}"
将确保事件仅在同一页面被刷新时加载,而不是在第一次加载时加载 -
listener
将引用一个后台bean方法,您可以在其中执行所需的验证。在这个侦听器中,您可以抛出ValidationException
,也可以适当地将FacesMessages
排队
选择:
你可以在
viewParam
中引用组件的值,并将相同的验证器附加到该组件:<f:metadata> <f:viewParam name="theParam" rendered="#{facesContext.postBack}" value="param['form:input2']" validator="customValidator"/> </f:metadata>
这将尝试将
input2
组件的值作为视图参数重新提交。view参数(在这种用法中)与其他参数一样是UIComponent
,并且遵循相同的转换/验证语义。如果您希望对该组件的内容进行更复杂的处理,您还可以将整个组件作为
viewParam
的属性传递。首先将input2
组件绑定到页面作用域:<h:inputText id="input2" binding="#{input2}" value="#{bean.property}"> <f:validator validatorId="customValidator" /> <f:ajax execute="@form" render="@this" /> </h:inputText>
然后将组件作为属性传递:
<f:metadata> <f:viewParam name="theParam" rendered="#{facesContext.postBack}" validator="customValidator"/> <f:attribute name="input2" value="#{input2}"/> </f:metadata>
然后您可以在验证器中检索值:
UIInput input2= (UIInput)component.getAttributes().get("input2");
String input2Value= input2.getSubmittedValue().toString();
您可以隐藏表单并使用JSF-AJAX节点的onevent属性。当AJAX响应被获取并设置您的表单可见时,它将被调用。
整个过程可以是这样的:
- 通过css使表单不可见。如
<form style="display:none">
- 您的
<f:ajax>
元素正在被处理。 - 在得到响应后,它的属性onevent被调用,并将设置你的表单可见。
提示:为了获得更好的外观,您可以使用JQuery来显示表单。使用如下:
$("#myform").fadeIn();