用于复合组件的Primefaces outputLabel [英] Primefaces outputLabel for composite component
问题描述
与复合组件一起使用时,我在使用p:outputLabel
时遇到问题.我有带p:inputText
字段的复合组件(我从组件中删除了不相关的部分):
I have an issue with using p:outputLabel
when used with composite component. I have composite component with p:inputText
field (I removed irrelevant parts from component):
<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
中使用此组件:
Now, I wont to use this component with p:outputLabel
:
<p:outputLabel for="myComponent:myInput" value="#{resources['myLabel']}:"/>
<my:myComponent id="myComponent" required="#{myBean.required}"/>
一切正常,需要验证,消息也会显示,但是标签上没有*
签名,就像我将标签直接连接到p:inputText
组件时一样.另一方面,如果我在p:inputText
上对required="true"
进行硬编码,则一切正常.
Everything works fine, required validation, message is displayed as well, but there is no *
sign on label, as there is when I connect label directly to p:inputText
component. If I, on the other hand, hardcode required="true"
on p:inputText
everything works fine.
我通过org.primefaces.component.outputlabel.OutputLabelRenderer
进行了调试,发现该组件被识别为UIInput
,但是input.isRequired()
返回false.进一步的调试发现required
属性尚未在组件上定义,因此它将false
作为默认值i UIInput
:
I debugged through org.primefaces.component.outputlabel.OutputLabelRenderer
and discovered that component is recognized as UIInput
, but input.isRequired()
returns false. Farther debugging discovered that required
attribute isn't yet defined on component, so it returns false
as default value i UIInput
:
(Boolean) getStateHelper().eval(PropertyKeys.required, false);
此外,如果我只是在复合组件内移动p:outputLabel
,一切都会很好.像EL稍后在复合组件内部进行评估?
Also, if I just move p:outputLabel
inside composite component everything works fine. Like EL is evaluated later inside composite component?
我在Mojarra 2.1.14中使用了Primefaces 3.5
I'm using Primefaces 3.5 with Mojarra 2.1.14
推荐答案
不幸的是,这是设计使然". #{}
表达式的求值被推迟到访问时间的确切时刻.它们与JSP 未中评估的标准" EL ${}
不同,后者是在标记处理程序对其进行解析并被缓存"以在同一请求/视图期间将来访问的确切时刻进行评估的.在渲染<p:outputLabel>
的那一刻,因此需要评估UIInput#isRequired()
引用的#{cc.attrs.required}
,在EL上下文中没有任何#{cc}
的手段.因此,它的任何属性都不会评估任何东西.只有当您坐在<cc:implementation>
中时,#{cc}
才可以在EL上下文中使用,因此其所有属性都可以成功进行评估.
This is, unfortunately, "by design". The evaluation of the #{}
expressions is deferred to the exact moment of the access-time. They're unlike "standard" EL ${}
in JSP not evaluated at the exact moment they're been parsed by the tag handler and "cached" for future access during the same request/view. At the moment the <p:outputLabel>
is rendered, and thus the #{cc.attrs.required}
as referenced by UIInput#isRequired()
needs to be evaluated, there's no means of any #{cc}
in the EL context. So any of its attributes would not evaluate to anything. Only when you're sitting inside the <cc:implementation>
, the #{cc}
is available in the EL context and all of its attribues would thus successfully evaluate.
从技术上讲,这是<p:outputLabel>
设计中不幸的极端情况.即,标准JSF和EL的行为符合规定.基本上,应根据输入的required
属性来评估标签星号的显示方式:在组合内部的<p:inputText>
呈现时,或者甚至在构建时,也应进行呈现.因此,标签组件不应询问输入组件是否需要,但输入组件应以某种方式通知标签组件它是必需的.反过来,这实现起来又困难又笨拙(因此效率低下).
Technically, this is an unfortunate corner case oversight in the design of <p:outputLabel>
. Standard JSF and EL are namely behaving as specified. Basically, the presentation of the label's asterisk depending on the input's required
attribute should be evaluated the other way round: at the moment the <p:inputText>
inside the composite is to be rendered or perhaps even already when it's to be built. Thus, the label component should not ask the input component if it's required, but the input component should somehow notify the label component that it's required. This is in turn hard and clumsy (and thus inefficient) to implement.
如果不选择将标签移动到复合材料内部,那么最好的选择是在输入部件周围创建一个标记文件,而不是复合部件.它只需要一些其他的XML样板即可.
If moving the label to inside the composite is not an option, then your best bet is to create a tag file instead of a composite component around the input component. It only requires some additional XML boilerplate.
/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}" />
我只是做了一个快速测试,对我来说很好.
I just did a quick test and it works fine for me.
这篇关于用于复合组件的Primefaces outputLabel的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!