EL-条件运算符 ?: 在复合组件中的意外行为
EL-Conditional operator ?: in composite component unexpected behavior
野飞8、JSF 2.2
如果复合组件中的条件运算符 ? :
与 c:foreach
循环中的列表一起使用,则其行为不正确。
示例文件的输出是
eng germ ital
并不像预期的那样
eng eng germ germ ital ital
如果复合组件重写为ui:include
或taglib
那么预期的结果就来了
文件(test.xhtml):
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:fn="http://java.sun.com/jsp/jstl/functions" xmlns:my="http://java.sun.com/jsf/composite/myComp"
xmlns:c="http://java.sun.com/jsp/jstl/core">
<h:body>
<my:testConditionalOperator languagesList="#{['eng', 'germ', 'ital']}"></my:testConditionalOperator>
</h:body>
</html>
复合组件(testConditionalOperator.xhtml):
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:a="http://xmlns.jcp.org/jsf/passthrough"
xmlns:of="http://omnifaces.org/functions" xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:c="http://java.sun.com/jsp/jstl/core" xmlns:o="http://omnifaces.org/ui" xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets" xmlns:fn="http://xmlns.jcp.org/jsp/jstl/functions"
xmlns:cc="http://java.sun.com/jsf/composite">
<cc:interface>
<cc:attribute name="languagesList"></cc:attribute>
</cc:interface>
<cc:implementation>
<c:forEach var="language" items="#{cc.attrs.languagesList}" >
#{fn:length(cc.attrs.languagesList) gt 1 ? language : "a"}
<c:if test="#{fn:length(cc.attrs.languagesList) gt 1}">
#{language}
</c:if>
</c:forEach>
</cc:implementation>
</html>
这似乎是一个没有出现在 MyFaces 中的 Mojarra 错误。
解决方法是,在 end
属性中设置大小并使用 varStatus
获取它。
<cc:implementation>
<c:forEach var="language" items="#{cc.attrs.languagesList}" end="#{cc.attrs.languagesList.size()}" varStatus="loop">
#{loop.end gt 1 ? language : "a"}
<c:if test="#{loop.end gt 1}">
#{language}
</c:if>
</c:forEach>
</cc:implementation>
注意 EL 2.2 仅使用 size()
而不是 fn:length()
的能力
野飞8、JSF 2.2
如果复合组件中的条件运算符 ? :
与 c:foreach
循环中的列表一起使用,则其行为不正确。
示例文件的输出是
eng germ ital
并不像预期的那样
eng eng germ germ ital ital
如果复合组件重写为ui:include
或taglib
那么预期的结果就来了
文件(test.xhtml):
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:fn="http://java.sun.com/jsp/jstl/functions" xmlns:my="http://java.sun.com/jsf/composite/myComp"
xmlns:c="http://java.sun.com/jsp/jstl/core">
<h:body>
<my:testConditionalOperator languagesList="#{['eng', 'germ', 'ital']}"></my:testConditionalOperator>
</h:body>
</html>
复合组件(testConditionalOperator.xhtml):
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:a="http://xmlns.jcp.org/jsf/passthrough"
xmlns:of="http://omnifaces.org/functions" xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:c="http://java.sun.com/jsp/jstl/core" xmlns:o="http://omnifaces.org/ui" xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets" xmlns:fn="http://xmlns.jcp.org/jsp/jstl/functions"
xmlns:cc="http://java.sun.com/jsf/composite">
<cc:interface>
<cc:attribute name="languagesList"></cc:attribute>
</cc:interface>
<cc:implementation>
<c:forEach var="language" items="#{cc.attrs.languagesList}" >
#{fn:length(cc.attrs.languagesList) gt 1 ? language : "a"}
<c:if test="#{fn:length(cc.attrs.languagesList) gt 1}">
#{language}
</c:if>
</c:forEach>
</cc:implementation>
</html>
这似乎是一个没有出现在 MyFaces 中的 Mojarra 错误。
解决方法是,在 end
属性中设置大小并使用 varStatus
获取它。
<cc:implementation>
<c:forEach var="language" items="#{cc.attrs.languagesList}" end="#{cc.attrs.languagesList.size()}" varStatus="loop">
#{loop.end gt 1 ? language : "a"}
<c:if test="#{loop.end gt 1}">
#{language}
</c:if>
</c:forEach>
</cc:implementation>
注意 EL 2.2 仅使用 size()
而不是 fn:length()