JSF渲染:EL语句的条件不正确

Men*_*nno 2 java jsf rendering el conditional-statements

我的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}" />
Run Code Online (Sandbox Code Playgroud)

例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>
Run Code Online (Sandbox Code Playgroud)

问题

在这两个示例中,我的两个参数都将添加到我周围的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>
Run Code Online (Sandbox Code Playgroud)

我已经清理了这个例子,但其实质是存在的.我已经用when/otherwise构造替换了第一个例子,无论我的product.category.parent.uri是否为null,它都会在这种情况下给出第一个结果.

Bal*_*usC 10

您的核心问题是您完全混淆视图构建时间标记和查看渲染时间标记.

视图构建时间是将XHTML文件转换为可用的JSF组件树的时刻FacesContext#getViewRoot().视图呈现时间是JSF组件树即将生成HTML代码的时刻UIViewRoot#encodeAll().

所有的JSTL <c:xxx>标签和所有JSF <ui:xxx>里面做标签具有rendered在视图生成时运行属性.所有的JSF <ui:xxx>标签来有一个rendered属性,所有的JSF <h:xxx>视图渲染时间期间运行的标签.因此,它们不会像编码所期望的那样同步运行.

回到你的具体问题,这是双重的:

  1. <f:param>不为标记处理程序不支持该rendered属性的.

  2. #{product}是你的代码由definied <ui:repeat var>,这是一个视图渲染时间标记,但尚未你试图让JSTL <c:xxx>视图生成时间标签依赖于这一点.这当然行不通.该#{product}null在视图生成时,仅仅是因为<ui:repeat>没有在那一刻运行.

您的具体问题只能通过使用视图构建时标记<c:forEach>而不是视图渲染时间标记<ui:repeat>来迭代产品来解决.

<c:forEach items="#{webshop.productlist}" var="product">
Run Code Online (Sandbox Code Playgroud)

也可以看看


具体问题无关,后续笨拙的阻碍

<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>
Run Code Online (Sandbox Code Playgroud)

在EL的条件运算符的帮助下,可以用以下更简单的方法替换:

<f:param name="cat" value="#{empty product.category.parent.uri ? product.category.uri : product.category.parent.uri}" />
Run Code Online (Sandbox Code Playgroud)

这样你必须能够继续使用<ui:repeat>.