我的输入字段附加了一个<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>
上。这是有效的,但网站被绘制了两次 - 如果由于页面首先被绘制而没有邪恶的闪烁,我将不会非常关心,然后进行验证&amp;通过ajax请求更新。
我已经搜索了几个小时来解决这个问题,也许我只是在错误的方向搜索。有关如何解决此问题的任何建议吗?
答案 0 :(得分:2)
不要使用@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
组件的值作为视图参数。视图参数(在此用法中)与任何其他参数一样是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();
答案 1 :(得分:0)
您可以隐藏表单并使用JSF-AJAX节点的 onevent 属性。 当获取AJAX响应并将表单设置为可见时,将调用它。
所以整个过程可能就像:
<form style="display:none">
<f:ajax>
元素。提示:为了更好的外观和感觉,您可以使用JQuery来显示表单。使用它像:
$("#myform").fadeIn();