复合组件的 Primefaces outputLabel [英] Primefaces outputLabel for composite component

查看:26
本文介绍了复合组件的 Primefaces outputLabel的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当与复合组件一起使用时,我在使用 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() 返回假.进一步调试发现 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?

我使用的是 Primefaces 3.5 和 Mojarra 2.1.14

I'm using Primefaces 3.5 with Mojarra 2.1.14

推荐答案

不幸的是,这是设计使然".#{} 表达式的计算推迟到访问时间的确切时刻.它们与标准"不同.JSP 中的 EL ${} 不会在它们被标记处理程序解析并缓存"的确切时刻进行评估.以供将来在同一请求/查看期间访问.目前 被渲染,因此 #{cc.attrs.required}UIInput#isRequired()<引用/code> 需要评估,在 EL 上下文中没有任何 #{cc} 方法.所以它的任何属性都不会评估为任何东西.只有当您坐在 中时,#{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.

从技术上讲,这是 设计中的一个不幸的角落案例疏忽.标准 JSF 和 EL 即按规定运行.基本上,取决于输入的 required 属性的标签星号的呈现应该以相反的方式进行评估:此时复合中的 是被渲染,或者甚至在它要建造的时候已经.因此,标签组件不应该询问输入组件是否需要它,但输入组件应该以某种方式通知标签组件它是必需的.这反过来又难以实施且笨拙(因此效率低下).

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆