我有一个复合组件(collapsiblePanel)。该组件使用“collapsible”bean 来提供切换功能。当我在一个页面上多次使用同一个组件时,该组件的每个实例都绑定(bind)到同一个 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;
}
}
使用页面
<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>
最佳答案
您可以使用componentType
<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;
}
}
但是,当您想要拥有多个这些组件时,您应该在 View 中声明它们的物理上独立的实例。如果这需要动态发生,那么您需要使用 <c:forEach>
生成它们的物理上独立的实例,而不是 <ui:repeat>
具有单个组件。否则你必须映射所有 collapsed
由 Map<String, Boolean>
内的客户端 ID 表示。另请参阅示例和更多背景信息 Getting same instance of `componentType` in composite component on every use
关于jsf-2 - 将托管 Bean 实例绑定(bind)到复合组件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6602953/