c:何时和c:如果不起作用

时间:2010-07-29 10:40:03

标签: jsf jstl

我可以从我的JSF2页面访问存储在辅助bean中的变量,所以像

这样的东西
<h:outputText value="#{myBean.myValue}"/>

工作,并且值( int btw。)打印正常。 但是,当尝试在c:if和/或c:中的条件表达式中使用此值时,标签永远不会等于任何东西......所以:

<c:if test="#{myBean.myValue == 1}">
    <c:set var="myVar" value="true"/>
</c:if>

<c:choose>
    <c:when test="#{myBean.myValue > 1}">
        <c:set var="myVar" value="true"/>
    </c:when>
</c:choose>

甚至

#{myBean.myValue eq '1'} 

#{myBean.myValue == '1'}

永远不会评估为true,即使该值确实为1或> 1。

令人讨厌的是,比较适用于标签的呈现属性!所以这个:

<h:outputText value="whatever" rendered="#{myBean.myValue == 1}"/>

很好!

发生了什么事?

更新

这有效:

public int getMyValue() {
    return 1;
}

但这不是:

@Column(name = "orderstatus")
public int getOrderStatus() {
return orderStatus;
}

正确打印int的值,但1 == 1为false。

实体bean是否以特殊方式处理?我可以使用它们在UI上显示它们的值吗?

UPDATE2:

<h:outputText value="#{order.adcOrderStatus.orderStatus.class}"/>

打印java.lang.Integer。

UPDATE3:

以下是完整代码:

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:c="http://java.sun.com/jsp/jstl/core"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:cc="http://java.sun.com/jsf/composite">
    <cc:interface>
        <cc:attribute name="orderStatus" required="true"/>
    </cc:interface>
    <cc:implementation>
        <c:choose>
            <c:when test="#{cc.attrs.orderStatus == 1}" >
                <c:set var="unknownStatus" value="false"/>
            </c:when>
            <c:when test="#{cc.attrs.orderStatus == 2}" >
                <c:set var="unknownStatus" value="false"/>
            </c:when>
            <c:when test="#{cc.attrs.orderStatus == 3}" >
                <c:set var="unknownStatus" value="false"/>
            </c:when>
            <c:when test="#{cc.attrs.orderStatus == 99}" >
                <c:set var="unknownStatus" value="false"/>
            </c:when>
            <c:otherwise>
                <c:set var="unknownStatus" value="true"/>
            </c:otherwise>
        </c:choose>
        <h:graphicImage url="#{resource['img/icons/flag_yellow.png']}" rendered="#{cc.attrs.orderStatus == 1}"/>
        <h:outputText value="Created" rendered="#{cc.attrs.orderStatus == 1}"/>
        <h:graphicImage url="#{resource['img/icons/flag_orange.png']}" rendered="#{cc.attrs.orderStatus == 2}"/>
        <h:outputText value="Stopped" rendered="#{cc.attrs.orderStatus == 2}"/>
        <h:graphicImage url="#{resource['img/icons/flag_green.png']}" rendered="#{cc.attrs.orderStatus == 3}"/>
        <h:outputText value="Active" rendered="#{cc.attrs.orderStatus == 3}"/>
        <h:graphicImage url="#{resource['img/icons/flag_red.png']}" rendered="#{cc.attrs.orderStatus == 99}"/>
        <h:outputText value="Failed" rendered="#{cc.attrs.orderStatus == 99}"/>
        <h:graphicImage url="#{resource['img/icons/question_mark.png']}" rendered="#{unknownStatus}"/>
        <h:outputText value="Unknown" rendered="#{unknownStatus}"/>
    </cc:implementation>
</html>

使用int值调用时有效。但这不起作用:

    <p:dataTable value="#{cc.attrs.orders}" var="order">
        <p:column>
            <f:facet name="header">
                <h:outputText value="Status"/>
            </f:facet>
            <mytag:orderStatus orderStatus="#{order.adcOrderStatus.orderStatus}"/>
        </p:column>
    </p:dataTable>

这会显示正确的值:

<h:outputText value="#{order.adcOrderStatus.orderStatus.class}"/>

3 个答案:

答案 0 :(得分:22)

您是否按如下方式声明了JSTL核心taglib?

<html xmlns:c="http://java.sun.com/jsp/jstl/core">

如果没有或错误地声明它们,它们将不会被解析并在生成的HTML输出中结束普通的香草。您可以通过在浏览器中打开页面,右键单击并选择查看源来确认这一点。你不应该在那里看到任何JSTL标签。


更新:根据您的更新,它与JSTL在视图的构建时间和JSF在视图的渲染时间内运行这一事实有关。在您的特定情况下,如果#{cc.attrs.orderStatus}仅在视图的渲染时间内可用,则全部都会失败。例如,当它表示迭代组件的当前迭代项时,例如<h:dataTable>

您最好按如下方式重写复合组件,以改为使用rendered属性:

<h:panelGroup rendered="#{cc.attrs.orderStatus == 1}">
    <h:graphicImage url="#{resource['img/icons/flag_yellow.png']}" /> Created
</h:panelGroup>
<h:panelGroup rendered="#{cc.attrs.orderStatus == 2}">
    <h:graphicImage url="#{resource['img/icons/flag_orange.png']}" /> Stopped
</h:panelGroup>
<h:panelGroup rendered="#{cc.attrs.orderStatus == 3}">
    <h:graphicImage url="#{resource['img/icons/flag_green.png']}" /> Active
</h:panelGroup>
<h:panelGroup rendered="#{cc.attrs.orderStatus == 99}">
    <h:graphicImage url="#{resource['img/icons/flag_red.png']}"  /> Failed
</h:panelGroup>
<h:panelGroup rendered="#{cc.attrs.orderStatus != 1 && cc.attrs.orderStatus != 2 && cc.attrs.orderStatus != 3 && cc.attrs.orderStatus != 99}">
    <h:graphicImage url="#{resource['img/icons/question_mark.png']}" /> Unknown
</h:panelGroup>

另见:

答案 1 :(得分:5)

<c:if test="#{myBean.myValue == 1}">

在JSF2之前,这些类似JSTL的Facelets标记仅在树创建时(ref)进行评估。

JSF2 doc for c:if没有提到这个,我知道两个Facelets版本不兼容(在规范中肯定是)并且我不清楚“处理过的”是什么意味着在这种情况下。可能值得仔细阅读规范以查看它是否更详细地描述了行为,在运行时检查component tree中的内容并在创建视图时检查对象状态。

答案 2 :(得分:1)

在大多数情况下可以使用rendered-Attribute替换,在某些情况下,您可以添加一些中性额外组件,例如。

因为有一个替代方案,它与JSF Lifecycle一起工作更轻量级:

<e:div>
    <h:selectBooleanCheckbox id="boolean" value="#{bean.value}" rendered="#{bean.type == 'boolean'}"/>
    ...
    <e:otherwise>
        <h:inputText id="text" value="#{bean.value}"/>
    </e:otherwise>
</e:div>

您可以从http://www.intersult.com/wiki/page/JSF%20Ext#section-JSF+Ext-OtherwiseTag进行配置(请使用页面翻译)。