覆盖复合组件中输入的默认验证器

时间:2015-01-30 13:08:58

标签: validation jsf jsf-2.2 composite-component

我正在使用默认验证器开发复合组件,该验证器可以与限制性更强的自定义验证器一起使用。但是,它并没有像预期的那样发挥作用。

我将问题归结为如下:

<h:inputText id="textId" value="#{bean.text}">
    <f:validateLength for="textId" maximum="10" />
    <f:validateLength for="textId" maximum="5" />
</h:inputText>

maximum=5的验证未执行或省略结果,因为只有maximum=10规则会产生正确的反馈:

Text field: 1234567890123

  

searchForm:textId:验证错误:长度大于允许的最大值&#39; 10&#39;

Text field: 1234567

  

这种行为背后的原因是什么?我怎么能达到我的要求呢?

1 个答案:

答案 0 :(得分:1)

从您的评论中,我假设您有一个这样的组件:

<cc:interface >
    <cc:editableValueHolder name="text" targets="myText"  />
</cc:interface>
<cc:implementation>
    <h:inputText id="myText">
        <f:validateLength maximum="10" />
    </h:inputText>
</cc:implementation>

你想要使用它 - 假设它被称为myInput - 就像这样:

<ns:myInput>
    <f:validateLength maximum="5" for="text" />
</ns:myInput>

因此,如果没有给出validateLength,则应该应用10,否则应用另一个值,如果它更具限制性。

我认为这是设计上的,你只能使用一个验证器来获得某种验证类型。因此,要解决此问题,您有3个选择:

首先,您可以在组件中使用正则表达式验证程序,例如:

   <h:inputText id="myText">
        <f:validateRegex pattern=".{,10}" />
    </h:inputText>

这将允许组件用户应用他自己的f:validateLength。但是那时候。他将无法再申请自己的f:validateRegex

另一个选项是,使组件用户能够使用组件属性禁用内置验证。但是,如果用户决定禁用它,那么这将完全绕过你的长度10的约束。

最佳选择(imho)是将maxLength应用为自己的属性,并根据您的最大约束验证该选项。 10位数:

<cc:interface >
    <cc:attribute name="maxLength" required="false" default="10"/>
</cc:interface>
<cc:implementation>
    <h:inputText id="myText">
        <f:validateLength maximum="#{(cc.attrs.maxLength > 10)? 10 : cc.attrs.maxLength}" />
    </h:inputText>
</cc:implementation>

现在用法是:

<ns:myInput maxLength="15">
    <!-- This will apply your contraint of 10 -->
</ns:myInput>

<ns:myInput maxLength="3">
    <!-- This will apply the component users constraint of 3 -->
</ns:myInput>

这也有一个好处,即组件用户不需要知道封装的editableValueHolder的实际名称,以便应用f:validateLength

还要考虑一下,如果真的有意限制组件内的maxLength。组件应该能够适用于所设计数据类型的任何用例,除非它们控制组件的外观,例如列数,每页项目数等。