我正在尝试为一个按钮创建一个JSF 2.1复合组件:
<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:composite="http://java.sun.com/jsf/composite"
xmlns:a4j="http://richfaces.org/a4j"
xmlns:rich="http://richfaces.org/rich"
xmlns:c="http://java.sun.com/jstl/core">
<composite:interface>
<composite:attribute name="id" required="true" type="java.lang.String" />
<composite:attribute name="label" required="true" type="java.lang.String" />
<composite:attribute name="action" method-signature="java.lang.String action()" targets="#{cc.attrs.id}" />
</composite:interface>
<composite:implementation>
<a4j:commandLink id="#{cc.attrs.id}">
<span style="linkButton"><h:outputText value="#{cc.attrs.label}" /></span>
</a4j:commandLink>
</composite:implementation>
</html>我在这段代码中遇到的问题是,在呈现页面时,它会给出以下异常:
java.lang.ClassCastException: javax.faces.component.UINamingContainer cannot be cast to javax.faces.component.ActionSource2
at com.sun.faces.application.view.FaceletViewHandlingStrategy$MethodRetargetHandlerManager$ActionRegargetHandler.retarget(FaceletViewHandlingStrategy.java:1536)
at com.sun.faces.application.view.FaceletViewHandlingStrategy.retargetMethodExpressions(FaceletViewHandlingStrategy.java:689)
at com.sun.faces.facelets.tag.jsf.CompositeComponentTagHandler.applyNextHandler(CompositeComponentTagHandler.java:201)
at org.richfaces.view.facelets.html.BehaviorsAddingComponentHandlerWrapper.applyNextHandler(BehaviorsAddingComponentHandlerWrapper.java:53)
at com.sun.faces.facelets.tag.jsf.ComponentTagHandlerDelegateImpl.apply(ComponentTagHandlerDelegateImpl.java:196)
...当我将id和targets属性中的#{cc.attrs.id}替换为已定义的字符串(如myId )时,组件将按预期工作,但这使得它不能在同一个页面中重用,从而消除了创建复合组件时的混乱感觉。
我错过了什么吗?
发布于 2013-11-19 00:57:31
在JSF组件树中,<cc:implementation>本身已经使用了#{cc.attrs.id}。您不应该在另一个组件上重用任何使用过的组件ID。你的具体功能需求不明确,抱怨“不能在同一页中重用”真的没有意义,因为它工作得很好(你真的试过并调查过生成的HTML输出吗?),所以很难理解你到底面临着什么问题。也许您完全忽略了复合组件隐含地继承自NamingContainer,并且已经将自己的id添加到子组件的id之前,就像<h:form>、<h:dataTable>等一样?
如果您唯一的需求是能够像在<f:ajax render="compositeId" />中那样通过ajax从外部引用复合组件,那么您需要将<cc:implementation>主体包装在一个普通的HTML <span>或<div>中,而不是使用#{cc.clientId},如下所示:
<div id="#{cc.clientId}">另请参阅:
https://stackoverflow.com/questions/20053256
复制相似问题