将托管bean实例绑定到复合组件

时间:2011-07-06 21:04:13

标签: jsf-2 composite-component managed-bean

我有一个复合组件(collapsiblePanel)。该组件使用“可折叠”bean来提供切换功能。当我在页面上多次使用相同的组件时,组件的每个实例都绑定到同一个bean实例。我怎样才能实现类似组件范围的bean?

collapsibleTemp.xhtml

<cc:interface>
    <cc:attribute name="model" required="true">
        <cc:attribute name="collapsed" required="true" />
        <cc:attribute name="toggle" required="true"
            method-signature="java.lang.String f()" />
    </cc:attribute>
    <cc:actionSource name="toggle" />
    <cc:facet name="header" />
    <cc:facet name="body" />
</cc:interface>
<cc:implementation>
    <h:panelGroup layout="block" styleClass="collapsiblePanel-header">
        <h:commandButton id="toggle" action="#{cc.attrs.model.toggle}"
            styleClass="collapsiblePanel-img"
            image="#{cc.attrs.model.collapsed ? '/resources/images/plus.png' : '/resources/images/minus.png'}" />
        <cc:renderFacet name="header" />
    </h:panelGroup>
    <h:panelGroup layout="block" rendered="#{!cc.attrs.model.collapsed}">
        <cc:insertChildren />
        <cc:renderFacet name="body"></cc:renderFacet>
    </h:panelGroup>
    <h:outputStylesheet library="css" name="components.css" />
</cc:implementation>

支持bean:

@ManagedBean
@ViewScoped
public class Collapsible {

    private boolean collapsed = false;

    public boolean isCollapsed() {
        return collapsed;
    }

    public void setCollapsed(boolean collapsed) {
        this.collapsed = collapsed;
    }

    public String toggle() {
        collapsed = !collapsed;
        return null;
    }

}

使用Page

<h:form id="someid">
    <jl:collapsibletemp id="collapsiblePanel1" model="#{collapsible}">
        <f:facet name="header">
            <h3>
                <h:outputText value="Collapsible information" />
            </h3>
        </f:facet>
        <f:facet name="body">
            <h:outputText value="do something....." />
        </f:facet>
        <p />
    </jl:collapsibletemp>

    <jl:collapsibletemp id="collapsiblePanel2" model="#{collapsible}">
        <f:facet name="header">
            <h3>
                <h:outputText value="Collapsible information" />
            </h3>
        </f:facet>
        <f:facet name="body">
            <h:outputText value="do some tabbing" />
        </f:facet>
        <p />
    </jl:collapsibletemp>

    <jl:collapsibletemp id="collapsiblePanel3" model="#{collapsible}">
        <f:facet name="header">
            <h3>
                <h:outputText value="Collapsible information" />
            </h3>
        </f:facet>
        <f:facet name="body">
            <h:outputText value="notice board" />
        </f:facet>
        <p />
    </jl:collapsibletemp>
</h:form>

1 个答案:

答案 0 :(得分:4)

您可以使用componentType的{​​{1}}属性来定义“支持组件”。

E.g。

<cc:interface>

只有一个<cc:interface componentType="collapsiblePanel"> ... </cc:interface> <cc:implementation> ... <h:commandButton action="#{cc.toggle}" ... /> ... <h:panelGroup rendered="#{!cc.collapsed}" ...> ... </cc:implementation>

com.example.components.CollapsiblePanel

但是,如果您想拥有多个这些组件,那么您应该在视图中声明它们的物理上分开的实例。如果这需要动态发生,那么您需要使用@FacesComponent(value="collapsiblePanel") // To be specified in componentType attribute. public class CollapsiblePanel extends UINamingContainer { // Important! Must extend UINamingContainer. private boolean collapsed; public void toggle() { collapsed = !collapsed; } public boolean isCollapsed() { collapsed; } } 生成物理上独立的实例,而不是<c:forEach>一个组件。否则,您必须通过<ui:repeat>内的客户端ID映射所有collapsed个状态。有关示例和更多背景信息,请参阅Getting same instance of `componentType` in composite component on every use