问题描述
我想为自定义组件创建验证器,并在其中传递一些属性.这就是代码的样子(它不是原始代码,但是以相同的方式实现):
I want to create validator for custom component where I want to pass few attributes. This is how code looks like (it's not original code but is implemented in the same way):
自定义组件(customComponent.xhtml)
Custom component (customComponent.xhtml)
<h:body>
<composite:interface componentType="compositeComponent">
<composite:attribute name="name" required="true" />
<composite:attribute name="value" required="true" />
<composite:attribute name="values" required="true" />
<composite:editableValueHolder name="validator" targets="#{cc.attrs.id}"/>
</composite:interface>
<composite:implementation>
<h:selectOneMenu value="#{cc.attrs.value}" id="#{cc.attrs.id}">
<f:selectItems value="#{cc.attrs.values}" var="item" itemValue="#{item.value}" itemLabel="#{item.label}" />
<composite:insertChildren/>
</h:selectOneMenu>
</composite:implementation>
</h:body>
如您所见,我想将验证器传递给h:selectOneMenu
.可以通过以下方式使用组件(准确地说是应该是",因为它当前不起作用):
As you can see I want to pass validator to h:selectOneMenu
. Component can be (to be more precisely 'should be' because it currently doesn't work) used in this way:
<ns:customComponent name="myComp" value="#{controller.value}" values="#{controller.values}">
<f:validator validatorId="myValidator" for="validator">
<f:attribute name="param1" value="param1Value"/>
<f:attribute name="param1" value="param1Value"/>
</validator>
</ns:customComponent>
我测试了此代码,如果我没有将属性传递给它,则调用验证程序.
I tested this code and validator is called if i don't pass attributes into it.
<ns:customComponent name="myComp" value="#{controller.value}" values="#{controller.values}">
<f:validator validatorId="myValidator" for="validator"/>
</ns:customComponent>
我发现属性可以通过这种方式传递:
I found that attributes can be passed in this way:
<ns:customComponent name="myComp" value="#{controller.value}" values="#{controller.values}">
<f:validator validatorId="myValidator" for="validator"/>
<f:attribute name="param1" value="param1Value"/>
<f:attribute name="param1" value="param1Value"/>
</ns:customComponent>
但是(据我所知),只有验证器会注入到自定义组件中(这就是为什么在验证器上设置for="validator"
的原因),所以我将无法获得这些属性.如何将属性传递给此验证器?
but (as far as I know) only validator will be injected to custom component (thats why for="validator"
is set on validator) so I won't be able to get these attributes. How can I pass attributes to this validator?
顺便说一句.如果可能的话,我希望将参数作为嵌套元素进行传递,因为它看起来更加清晰.这个:
BTW. If it's possible I will want to pass parameters as nested elements because it looks more clear. This one:
<f:selectOneMenu>
<f:validator validatorId="myValidator">
<f:attribute name="param1" value="value1"/>
</f:validator>
</f:selectOneMenu>
代替这个:
<f:selectOneMenu>
<f:validator validatorId="myValidator"/>
<f:attribute name="param1" value="value1"/>
</f:selectOneMenu>
推荐答案
我发现<f:validator/>
不能具有嵌套元素,因此该元素不起作用:
I found that <f:validator/>
cant have nested elements so this one won't work:
<f:validator validatorId="myValidator">
<f:attribute name="param1" value="value1"/>
</f:validator>
为解决我的问题,我创建了自定义验证器.为此,我必须:
To solve my problem I've created custom validator. To do it I had to:
在WEB-INF
目录中创建taglib.xml
文件.
<?xml version="1.0"?>
<!DOCTYPE facelet-taglib PUBLIC
"-//Sun Microsystems, Inc.//DTD Facelet Taglib 1.0//EN"
"http://java.sun.com/dtd/facelet-taglib_1_0.dtd">
<facelet-taglib>
<namespace>http://customtag.com/tags</namespace>
<tag>
<tag-name>uniqueValidator</tag-name>
<validator>
<validator-id>simpleValidator</validator-id>
</validator>
<!-- To show hints on this component add this but it's not required -->
<attribute>
<description>List of elements to check. Validation succeeds if each item is unique (equals() method is used to compare items).</description>
<name>items</name>
<required>true</required>
</attribute>
</tag>
</facelet-taglib>
在web.xml
<context-param>
<param-name>javax.faces.FACELETS_LIBRARIES</param-name>
<param-value>/WEB-INF/taglib.xml</param-value>
</context-param>
编写验证码
package validator;
import java.util.List;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.validator.FacesValidator;
import javax.faces.validator.Validator;
import javax.faces.validator.ValidatorException;
@FacesValidator("simpleValidator")
public class SimpleValidator implements Validator {
private List<Object> items;
@Override
public void validate(final FacesContext arg0, final UIComponent arg1, final Object arg2) throws ValidatorException {
// use items list
}
public void setItems(final List<Object> items) {
this.items = items;
}
}
这是在视图/复合组件中使用它的方式:
This is how it can be used in view / composite component:
<mycomp:custom name="test11">
<myval:uniqueValidator items="#{model.values}" for="validator"/>
</mycomp:custom>
当然要在自定义组件中使用验证器,我必须定义editableValueHolder
并使用insertChildren
注入/粘贴它(请参阅我的问题).
Of course to use validator in custom component I had to define editableValueHolder
and inject/paste it using insertChildren
(see my question).
这篇关于带有定制组件属性的验证器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!