<f:validator>
是一个标签处理器,而不是UI组件。所有的属性都在视图构建时被定义评估,而不是在视图渲染时评估。视图构建时间是指将XHTML文件解析为JSF组件树的那个时刻,这些组件可以通过
context.getViewRoot()
访问。通常情况下,通过在(ajax)操作中返回
null
/
void
来重用相同的视图。
因此,您不能使标签处理器属性依赖于可能在postback请求期间更改的渲染时间属性。其中一种方法是在自定义验证器本身内执行该检查。
例如:
<h:inputText>
<f:validator validatorId="myValidator" />
<f:attribute name="radio" value="#{myBean.checkedSelectOneRadioValue}" />
</h:inputText>
使用
@Override
public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException {
if (!"TEST".equals(component.getAttributes().get("radio"))) {
return;
}
}
你也可以使用
OmniFaces <o:validator>
。这个扩展了标准的
<f:validator>
,支持对属性中EL表达式的请求基础评估。
<h:inputText>
<o:validator validatorId="myValidator" disabled="#{bean.checkedSelectOneRadioValue == 'TEST'}" />
</h:inputText>
请参考
展示示例和
源代码,下面发布了一个相关的摘录:
@Override
public void apply(FaceletContext context, UIComponent parent) throws IOException {
if (!ComponentHandler.isNew(parent)) {
return;
}
final javax.faces.validator.Validator validator = createValidator(context);
final RenderTimeAttributes attributes = collectRenderTimeAttributes(context, validator);
final ValueExpression disabled = getValueExpression(context, "disabled", Boolean.class);
((EditableValueHolder) parent).addValidator(new javax.faces.validator.Validator() {
@Override
public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException {
if (disabled == null || Boolean.FALSE.equals(disabled.getValue(context.getELContext()))) {
attributes.invokeSetters(context.getELContext(), validator);
validator.validate(context, component, value);
}
}
});
}