11

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たところ、コンポーネントがとして認識されていることがわかりましたが、 falseUIInputが返されます。input.isRequired()さらにデバッグすると、required属性がコンポーネントでまだ定義されていないことが判明したためfalse、デフォルト値iとして返されますUIInput

(Boolean) getStateHelper().eval(PropertyKeys.required, false);

また、p:outputLabel複合コンポーネント内を移動するだけで、すべてが正常に機能します。ELは後で複合コンポーネント内で評価されるように?

Primefaces3.5とMojarra2.1.14を使用しています

4

1 に答える 1

13

残念ながら、これは「設計による」ものです。式の評価は#{}、アクセス時間の正確な瞬間に延期されます。${}これらは、JSPの「標準」ELとは異なり、タグハンドラーによって解析され、同じリクエスト/ビュー中に将来アクセスできるように「キャッシュ」された瞬間に評価されません。現時点では、<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}" />

簡単なテストを行ったところ、問題なく動作しました。

参照:

于 2013-02-25T14:43:32.403 に答える