我有使用问题 p:outputLabel
与复合材料组件一起使用时我有复合组件 p:inputText
字段(我从组件中删除了不相关的部分):
<cc:interface>
<cc:editableValueHolder name="myInput" targets="myInput"/>
<cc:attribute name="required" required="true" type="java.lang.Boolean" default="false"/>
</cc:interface>
<cc:implementation>
<p:inputText id="myInput" required="#{cc.attrs.required}"/>
</cc:implementation>
现在,我不会使用这个组件 p:outputLabel
:
<p:outputLabel for="myComponent:myInput" value="#{resources['myLabel']}:"/>
<my:myComponent id="myComponent" required="#{myBean.required}"/>
一切正常,需要验证,消息也显示,但没有 *
在标签上签名,因为我直接连接标签 p:inputText
零件。另一方面,如果我硬编码 required="true"
上 p:inputText
一切正常。
我通过调试 org.primefaces.component.outputlabel.OutputLabelRenderer
并发现该组件被识别为 UIInput
但是 input.isRequired()
返回false。进一步调试发现了这一点 required
属性尚未在组件上定义,因此返回 false
作为默认值i UIInput
:
(Boolean) getStateHelper().eval(PropertyKeys.required, false);
另外,如果我移动 p:outputLabel
内部复合组件一切正常。像EL一样,后来在复合元件内进行评估?
我正在使用Primefaces 3.5和Mojarra 2.1.14
不幸的是,这是“按设计”。评价 #{}
表达式被推迟到访问时间的确切时刻。它们与“标准”EL不同 ${}
在JSP中 不 在标记处理程序解析它们并在同一请求/视图中“缓存”以供将来访问的确切时刻进行评估。此刻 <p:outputLabel>
被渲染,因此 #{cc.attrs.required}
如引用 UIInput#isRequired()
需要评估,没有任何手段 #{cc}
在EL语境中。所以它的任何属性都不会评估任何东西。只有当你坐在里面 <cc:implementation>
, #{cc}
在EL环境中可用,因此它的所有属性都将成功评估。
从技术上讲,这是一个不幸的角落案例监督设计 <p:outputLabel>
。标准JSF和EL表现为指定的行为。基本上,标签的星号表示取决于输入 required
属性应该反过来评估:此刻 <p:inputText>
复合内部将被渲染,或者甚至已经建成。因此,标签组件不应询问输入组件是否需要,但输入组件应以某种方式通知标签组件它是否需要。这反过来又变得艰难而且笨拙(因而效率低下)。
如果将标签移动到复合材料内部不是一个选项,那么最好的办法是在输入组件周围创建一个标签文件而不是复合组件。它只需要一些额外的XML样板。
/WEB-INF/tags/input.xhtml
:
<ui:composition
xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:c="http://java.sun.com/jsp/jstl/core"
xmlns:p="http://primefaces.org/ui"
>
<c:set var="id" value="#{not empty id ? id : 'myInput'}" />
<c:set var="required" value="#{not empty required and required}" />
<p:inputText id="#{id}" required="#{required}"/>
</ui:composition>
/WEB-INF/my.taglib.xml
:
<?xml version="1.0" encoding="UTF-8"?>
<facelet-taglib
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facelettaglibrary_2_0.xsd"
version="2.0"
>
<namespace>http://example.com/my</namespace>
<tag>
<tag-name>input</tag-name>
<source>tags/input.xhtml</source>
</tag>
</facelet-taglib>
/WEB-INF/web.xml
:
<context-param>
<param-name>javax.faces.FACELETS_LIBRARIES</param-name>
<param-value>/WEB-INF/my.taglib.xml</param-value>
</context-param>
用法:
<html ... xmlns:my="http://example.com/my">
...
<p:outputLabel for="myInput" value="#{resources['myLabel']}:" />
<my:input id="myInput" required="#{myBean.required}" />
我刚做了一个快速测试,它对我来说很好。
也可以看看:
不幸的是,这是“按设计”。评价 #{}
表达式被推迟到访问时间的确切时刻。它们与“标准”EL不同 ${}
在JSP中 不 在标记处理程序解析它们并在同一请求/视图中“缓存”以供将来访问的确切时刻进行评估。此刻 <p:outputLabel>
被渲染,因此 #{cc.attrs.required}
如引用 UIInput#isRequired()
需要评估,没有任何手段 #{cc}
在EL语境中。所以它的任何属性都不会评估任何东西。只有当你坐在里面 <cc:implementation>
, #{cc}
在EL环境中可用,因此它的所有属性都将成功评估。
从技术上讲,这是一个不幸的角落案例监督设计 <p:outputLabel>
。标准JSF和EL表现为指定的行为。基本上,标签的星号表示取决于输入 required
属性应该反过来评估:此刻 <p:inputText>
复合内部将被渲染,或者甚至已经建成。因此,标签组件不应询问输入组件是否需要,但输入组件应以某种方式通知标签组件它是否需要。这反过来又变得艰难而且笨拙(因而效率低下)。
如果将标签移动到复合材料内部不是一个选项,那么最好的办法是在输入组件周围创建一个标签文件而不是复合组件。它只需要一些额外的XML样板。
/WEB-INF/tags/input.xhtml
:
<ui:composition
xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:c="http://java.sun.com/jsp/jstl/core"
xmlns:p="http://primefaces.org/ui"
>
<c:set var="id" value="#{not empty id ? id : 'myInput'}" />
<c:set var="required" value="#{not empty required and required}" />
<p:inputText id="#{id}" required="#{required}"/>
</ui:composition>
/WEB-INF/my.taglib.xml
:
<?xml version="1.0" encoding="UTF-8"?>
<facelet-taglib
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facelettaglibrary_2_0.xsd"
version="2.0"
>
<namespace>http://example.com/my</namespace>
<tag>
<tag-name>input</tag-name>
<source>tags/input.xhtml</source>
</tag>
</facelet-taglib>
/WEB-INF/web.xml
:
<context-param>
<param-name>javax.faces.FACELETS_LIBRARIES</param-name>
<param-value>/WEB-INF/my.taglib.xml</param-value>
</context-param>
用法:
<html ... xmlns:my="http://example.com/my">
...
<p:outputLabel for="myInput" value="#{resources['myLabel']}:" />
<my:input id="myInput" required="#{myBean.required}" />
我刚做了一个快速测试,它对我来说很好。
也可以看看: