8

我创建了一些 Facelets 来简化我们的页面开发。特别是,我为输入组件创建了一系列 Facelets。我有 1 个 Facelet,<xxx:input />它在输入字段周围显示一个标签。除此之外,我还有 Facelets <xxx:inputText /><xxx:inputSecret />它可以渲染实际的输入字段。这些中的每一个都<xxx:input />用于显示标签。Facelet 看起来像这样:

<html ...>
   <composite:interface>
      ...
   </composite:interface>
   <composite:implementation>
       <label><h:outputText value="#{cc.attrs.labelText}" /></label>

       <composite:insertChildren />
   </composite:implementation>
</html>

Facelet将<xxx:inputText />看起来像这样......

<html ...>
   <composite:interface>
      ...
   </composite:interface>
   <composite:implementation>
      <xxx:input labelText=...>
         <h:inputText id="myinput" ... />
      </xxx:input>
   </composite:implementation>
</html>

一切都很好,但我在尝试添加<f:validator />或其他验证标签时遇到了麻烦。根据我的阅读,我必须在我的 Facelet 中添加一个标签。所以,我<composite:editableValueHolder name="myinput" targets="myinput" />在界面部分添加了一行。但是,我仍然没有看到我的验证器被解雇。我的 .xhtml 文件中有类似的内容...

 ...
    <xxx:inputText value="...">
      <f:validateLength minimum="10" for="myinput" />
    </xxx:inputText>
    ...

无论我输入什么输入,验证器似乎都不会触发,我也从未收到错误消息。一位同事建议这是由于我使用的目标 ID 以及它被<xxx:input />Facelet 包装的事实。

我是否需要在我的目标定义中加入父组件 ID?还有什么我想念的吗?如果我排除<xxx:input />Facelet,它就可以正常工作,所以我假设它与此相关,但不知道如何解决它。非常感谢您提供的任何帮助。

4

1 回答 1

9

您需要指定验证器的属性for以匹配name.<composite:editableValueHolder>

<xxx:inputText value="...">
  <f:validateLength for="myinput" minimum="10" />
</xxx:inputText>

您还需要确保在两个组合中都<composite:editableValueHolder>指定了 ,因此也需要在组合中指定。这是一个完整的示例,在 Mojarra 2.1.12 上对我来说效果很好:input.xhtml

/resources/components/input.xhtml

<ui:component
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:cc="http://java.sun.com/jsf/composite"
>
    <cc:interface>
        <cc:attribute name="label" required="true" />
        <cc:editableValueHolder name="input" targets="input" />
    </cc:interface>
    <cc:implementation>
       <h:outputLabel for="input" value="#{cc.attrs.label}" />
       <cc:insertChildren />
    </cc:implementation>
</ui:component>

/resources/components/inputText.xhtml

<ui:component
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:cc="http://java.sun.com/jsf/composite"
    xmlns:my="http://java.sun.com/jsf/composite/components"
>
    <cc:interface>
        <cc:attribute name="label" required="true" />
        <cc:attribute name="value" required="true" />
        <cc:editableValueHolder name="input" targets="input:text" />
    </cc:interface>
    <cc:implementation>
        <my:input id="input" label="#{cc.attrs.label}">
            <h:inputText id="text" value="#{cc.attrs.value}" />
        </my:input>
    </cc:implementation>
</ui:component>

在某些方面的用法test.xhtml

<!DOCTYPE html>
<html lang="en"
    xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:my="http://java.sun.com/jsf/composite/components"
>
    <h:head>
        <title>SO question 12188638</title>
    </h:head>
    <h:body>
        <h:form>
            <my:inputText label="foo" value="#{bean.input}">
                <f:validateLength minimum="10" for="input" />
            </my:inputText>
            <h:commandButton value="submit" action="#{bean.submit}">
                <f:ajax execute="@form" render="@form"/>
            </h:commandButton>
            <h:messages/>
        </h:form>
    </h:body>
</html>

也可以看看:


与具体问题无关,您知道<h:outputLabel>吗?

<h:outputLabel value="#{cc.attrs.labelText}" />

事实上,您可以在模板文本中内联 EL 而无需明确需要<h:outputText>?

<label>#{cc.attrs.labelText}</label>

您是否注意到您的标签也缺少应该引用标签for应该引用的输入元素的 ID 的属性?

<h:outputLabel for="someId" ... />
<h:inputText id="someId" ... />
于 2012-08-30T03:33:50.393 回答