Jsf 2 复合组件的Primefaces outputLabel
当与复合组件一起使用时,我对使用Jsf 2 复合组件的Primefaces outputLabel,jsf-2,primefaces,composite-component,Jsf 2,Primefaces,Composite Component,当与复合组件一起使用时,我对使用p:outputLabel有一个问题。我有一个带有p:inputText字段的复合组件(我从组件中删除了不相关的部分): 一切正常,需要验证,也会显示消息,但标签上没有签名,就像我将标签直接连接到p:inputText组件时一样。另一方面,如果我在p:inputText上使用hardcoderequired=“true”,一切正常 我通过org.primefaces.component.outputlabel.OutputLabelRenderer进行调试,发现该
p:outputLabel
有一个问题。我有一个带有p:inputText
字段的复合组件(我从组件中删除了不相关的部分):
一切正常,需要验证,也会显示消息,但标签上没有签名,就像我将标签直接连接到p:inputText
组件时一样。另一方面,如果我在p:inputText
上使用hardcoderequired=“true”
,一切正常
我通过org.primefaces.component.outputlabel.OutputLabelRenderer
进行调试,发现该组件被识别为UIInput
,但input.isRequired()
返回false。进一步调试发现,required
属性尚未在组件上定义,因此它返回false
作为默认值iUIInput
:
(Boolean) getStateHelper().eval(PropertyKeys.required, false);
另外,如果我只是在复合组件中移动p:outputLabel
,一切都会正常工作。比如EL稍后在复合组件中进行评估
我在Mojarra 2.1.14中使用Primefaces 3.5,不幸的是,这是“设计的”。{}
表达式的计算延迟到访问时间的确切时刻。它们不同于JSP中的“标准”EL${}
,它们不是在被标记处理程序解析并“缓存”以供将来在同一请求/视图中访问时进行计算的。在呈现
的那一刻,因此需要对UIInput\isRequired()
引用的{cc.attrs.required}
进行评估,在EL上下文中没有任何{cc}
方法。因此,它的任何属性都不会计算为任何值。只有当您坐在
中时,{cc}
才能在EL上下文中使用,因此它的所有属性都将成功地进行评估
从技术上讲,这是
设计中一个令人遗憾的疏忽。标准JSF和EL的行为符合规定。基本上,标签星号的显示取决于输入的required
属性,应该以另一种方式进行评估:在合成图中的
将被渲染的时刻,或者甚至可能在构建它的时候。因此,标签组件不应该询问输入组件是否需要它,但是输入组件应该以某种方式通知标签组件它是需要的。这反过来又很难实现,也很笨拙(因此效率很低)
如果不选择将标签移动到组合内部,则最好是在输入组件周围创建标记文件,而不是组合组件。它只需要一些额外的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>
<?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>
<context-param>
<param-name>javax.faces.FACELETS_LIBRARIES</param-name>
<param-value>/WEB-INF/my.taglib.xml</param-value>
</context-param>
/WEB-INF/WEB.xml
:
<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>
<?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>
<context-param>
<param-name>javax.faces.FACELETS_LIBRARIES</param-name>
<param-value>/WEB-INF/my.taglib.xml</param-value>
</context-param>
javax.faces.FACELETS\u库
/WEB-INF/my.taglib.xml
用法:
<html ... xmlns:my="http://example.com/my">
...
<p:outputLabel for="myInput" value="#{resources['myLabel']}:" />
<my:input id="myInput" required="#{myBean.required}" />
...
我只是做了一个快速测试,对我来说效果很好
另见:
面板网格中使用,一列用于标签,一列用于输入。这样很难让它看起来可以接受。那么使用标记文件而不是复合组件对您来说有一个额外的优势:标记文件不同于复合组件,而不是解释为单个组件!事实上,您可以安全地将标签放在标记文件中输入的旁边,并且仍然有2个单元格。另请参阅,这将进一步简化样板文件。我已经找到了一种使用o:tagAttribute
的方法,但它从2.1开始就可以使用,而我们使用的是1.14,您是否计划在将来创建一个可能包含此内容的新版本?@Rapster Nope,1.1x已经过时了。JSF2.3是在几个月前引入的,它有一个必需的CDI依赖项。所以所有的焦点都集中在OmniFaces 2.x和3.x上。要在这篇文章中添加相关评论,p:outputLabel
现在支持复合,请参阅迁移指南,但我想得越多,我越觉得用例是错误的(使用复合),而应该使用facelet。更多解释如下: