2

JSFレンダリングに問題があります。式言語の特定の条件は、正しい方法で実行されません。例えば:

例1

<f:param name="cat" value="#{product.category.uri}" rendered="#{product.category.parent.uri == null}" />
<f:param name="cat" value="#{product.category.parent.uri}" rendered="#{product.category.parent.uri != null}" />

例2

<c:if test="#{product.category.parent.uri == null}">
    <f:param name="cat" value="#{product.category.uri}" />
</c:if>

<c:if test="#{product.category.parent.uri != null}">
    <f:param name="cat" value="#{product.category.parent.uri}" />
</c:if>

問題

どちらの例でも、両方のパラメーターが周囲のh:outputLinkに追加されます。他にどのコードを追加すればよいかわからないので、私を助けるために何か他のものが必要な場合は、喜んで提供します。

前もって感謝します。

例3(要求に応じて)

<?xml version='1.0' encoding='UTF-8' ?>

<ui:composition template="./WEB-INF/templates/base.xhtml"
                xmlns="http://www.w3.org/1999/xhtml"
                xmlns:ui="http://java.sun.com/jsf/facelets"
                xmlns:h="http://java.sun.com/jsf/html"
                xmlns:f="http://java.sun.com/jsf/core"
                xmlns:c="http://java.sun.com/jsp/jstl/core">
    <ui:define name="content">
        <c:choose>
            <c:when test="#{webshop.productlist.size() > 0}">
                <div id="spacer">
                    <ui:repeat value="#{webshop.productlist}" var="product">
                        <div id="block">
                            <p>
                                <h:outputLink value="product.xhtml">
                                    #{product.name}
                                    <c:choose>
                                        <c:when test="#{product.category.parent.uri == null}">
                                            <f:param name="cat" value="#{product.category.uri}" rendered="" />
                                        </c:when>
                                        <c:otherwise>
                                            <f:param name="cat" value="#{product.category.parent.uri}" />
                                        </c:otherwise>
                                    </c:choose>
                                    <f:param name="product" value="#{product.uri}" />
                                </h:outputLink>
                            </p>
                        </div>
                    </ui:repeat>
                </div>
            </c:when>

            <c:otherwise>
                (...)
            </c:otherwise>
        </c:choose>
    </ui:define>
</ui:composition>

この例を少しクリーンアップしましたが、本質はそこにあります。product.category.parent.uriがnullであるかどうかに関係なく、最初の例をwhen / else構文に置き換えました。この場合、最初の結果が得られます。

4

2 に答える 2

10

主な問題は、ビューのビルド時間タグとビューのレンダリング時間タグを完全に混同していることです。

ビューのビルド時間は、XHTMLファイルがで利用可能なJSFコンポーネントツリーに変換される瞬間ですFacesContext#getViewRoot()。ビューのレンダリング時間は、によって開始されるように、JSFコンポーネントツリーがHTMLコードを生成しようとしている瞬間UIViewRoot#encodeAll()です。

すべてのJSTLタグと、属性を持たない<c:xxx>すべてのJSFタグは、ビューのビルド時に実行されます。属性を持つすべてのJSFタグと、すべてのJSFタグ、ビューのレンダリング時に実行されます。したがって、コーディングから期待されるように、それらは同期して実行されません。<ui:xxx>rendered<ui:xxx>rendered<h:xxx>

具体的な問題に戻ると、これは2つあります。

  1. <f:param>タグハンドラであるため、rendered属性はまったくサポートされていません。

  2. これは、ビューレンダリングタイムタグである#{product}によって定義されたコード内にありますが、JSTLビュービルドタイムタグがそれに依存する<ui:repeat var>ようにしようとしています。<c:xxx>もちろん、これは機能しません。#{product}nullビューのビルド時間中です。これは、その時点でが実行されていないためです<ui:repeat>

具体的な問題<c:forEach>は、ビューレンダリングタイムタグの代わりにビュービルドタイムタグを使用<ui:repeat>して製品を反復処理することによってのみ解決できます。

<c:forEach items="#{webshop.productlist}" var="product">

も参照してください


具体的な問題とは関係なく、次の不器用なブロック

<c:choose>
    <c:when test="#{product.category.parent.uri == null}">
        <f:param name="cat" value="#{product.category.uri}" rendered="" />
    </c:when>
    <c:otherwise>
        <f:param name="cat" value="#{product.category.parent.uri}" />
    </c:otherwise>
</c:choose>

ELの条件演算子を使用して、次のより単純なアプローチに置き換えることができます。

<f:param name="cat" value="#{empty product.category.parent.uri ? product.category.uri : product.category.parent.uri}" />

このようにして、を使い続けることができなければなりません<ui:repeat>

于 2012-09-07T19:35:03.037 に答える
0

ドキュメントによると、タグrenderedに使用できる属性がないため、無視されています。f:param

JSF<2.xについてはを参照してください-http ://docs.oracle.com/javaee/5/javaserverfaces/1.2/docs/tlddocs/f/param.html

JSF>2.0を参照してください-http://javaserverfaces.java.net/nonav/docs/2.0/pdldocs/facelets/f/param.html

product.category.parent.uriこれで、例2が引き続き機能することが示唆される可能性があるため、空(つまり空白の文字列)ではなく、実際にnullであるかどうかを疑問視する可能性があります。空をテストしようとしましたか(nullと空の文字列をチェックします)?

<c:if test="#{empty product.category.parent.uri}">  
<f:param name="cat" value="#{product.category.uri}" />  
</c:if>  

<c:if test="#{!empty product.category.parent.uri}">  
<f:param name="cat" value="#{product.category.parent.uri}" />
</c:if>

もう1つの方法は、理想的ではありませんが、条件付きで2つの別々の出力リンクをレンダリングし、値に基づいてどちらをレンダリングするかを決定することです。そのような:

<c:choose> 
  <c:when test="#{empty product.category.parent.uri}">
     <h:outputLink value="product.xhtml">
       <f:param name="cat" value="#{product.category.uri}"/>
       <f:param name="product" value="#{product.uri}" />
     </h:outputLink>
  </c:when>
  <c:otherwise>
     <h:outputLink value="product.xhtml">
        <f:param name="cat" value="#{product.category.parent.uri}" />
        <f:param name="product" value="#{product.uri}" />
     </h:outputLink>
  </c:otherwise>
</c:choose>
于 2012-09-07T19:32:26.177 に答える