在JSF 2复合组件中使用id-attribute和目标

Gan*_*alf 0 jsf el ajax4jsf composite-component jsf-2

我正在尝试为按钮创建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>
Run Code Online (Sandbox Code Playgroud)

我对此代码的问题是,在呈现页面时它会给出以下异常:

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

当我用一个定义的String 替换#{cc.attrs.id}in idtargets属性时,myId组件按预期工作,但这使得它不能在同一页面中重复使用,从而消除了创建复合组件的神奇感.

我在这里错过了吗?

Bal*_*usC 11

在JSF组件树中,#{cc.attrs.id}它已经被<cc:implementation>自己使用.您不应该在另一个组件上重用任何使用过的组件ID.您的具体功能要求不清楚,"在同一页面中无法重复使用"的投诉真的没有意义,因为它完全正常(您是否真的尝试过它并调查了生成的HTML输出?),所以很难理解你到底是什么问题面对.也许你完全忽略了复合材料部件隐含继承NamingContainer和已经在前面加上自己的ID给那些孩子,像如<h:form>,<h:dataTable>等还做什么?

如果您的唯一要求是能够通过ajax从外部引用复合组件<f:ajax render="compositeId" />,那么您需要将该主体包装<cc:implementation>成普通的HTML <span><div>如下所示#{cc.clientId}:

<div id="#{cc.clientId}">
Run Code Online (Sandbox Code Playgroud)

也可以看看: