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

Override default validator of input in 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: Validation Error: Length is greater than allowable maximum of '10'

Text field: 1234567

passes

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

根据你的评论,我假设你有这样一个组件:

<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。但是然后ofc。他将无法再应用自己的 f:validateRegex.

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

最好的选择(恕我直言)是将 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 是有意义的。组件应该能够适用于设计数据类型的任何用例,除非它们控制组件的外观,例如列数、每页项目等。