【问题标题】:Validator with attributes for custom component具有自定义组件属性的验证器
【发布时间】:2014-03-23 03:11:36
【问题描述】:

我想为我想传递一些属性的自定义组件创建验证器。这就是代码的样子(它不是原始代码,但以相同的方式实现):

自定义组件(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。组件可以(更准确地说是“应该”,因为它目前不起作用)以这种方式使用:

<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>

我测试了这段代码,如果我不向其中传递属性,就会调用验证器。

<ns:customComponent name="myComp" value="#{controller.value}" values="#{controller.values}">
    <f:validator validatorId="myValidator" for="validator"/>
</ns:customComponent>

我发现属性可以这样传递:

<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")所以我将无法获得这些属性。如何将属性传递给此验证器?

顺便说一句。如果可能的话,我希望将参数作为嵌套元素传递,因为它看起来更清晰。这个:

<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>

【问题讨论】:

    标签: jsf jsf-2


    【解决方案1】:

    我发现&lt;f:validator/&gt; 不能有嵌套元素,所以这个不起作用:

    <f:validator validatorId="myValidator">
        <f:attribute name="param1" value="value1"/>
    </f:validator>
    

    为了解决我的问题,我创建了自定义验证器。为此,我必须:

    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注册taglib.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;
        }
    
    }
    

    这是它在视图/复合组件中的使用方式:

    <mycomp:custom name="test11">
        <myval:uniqueValidator items="#{model.values}" for="validator"/>
    </mycomp:custom>
    

    当然要在自定义组件中使用验证器,我必须定义 editableValueHolder 并使用 insertChildren 注入/粘贴它(请参阅我的问题)。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-03-26
    • 1970-01-01
    • 1970-01-01
    • 2014-01-12
    • 1970-01-01
    • 1970-01-01
    • 2017-12-13
    相关资源
    最近更新 更多