I would like to have a reusable ui component which is tied to the model.
For example :
I think this idea works if im only using one compositeComponent.
But this will not work if i make use of more than one compositeComponent of the same type, since the compositeComponent's JSF Bean will be the same (in this example, im using view scope), and will share the state between one or more compositeComponents.
This is one rough example that illustrates my confusion. In this case, Page1.xhtml (with the main model of Page1Bean.java), makes use of 2 compositeComponents (which is handled by the JSF Bean of MyCompositeComponent.java)
The composite component will be something like :
<!-- one composite component that has 2 chained selectOneMenus -->
<h:selectOneMenu
...
value="#{myCompositeComponentBean.firstComboValue}"
valueChangeListener="#{myCompositeComponentBean.yyy}">
<f:ajax event="valueChange" execute="@this" ... />
<f:selectItem itemLabel="Choose one .." noSelectionOption="true" />
<f:selectItems value="#{myCompositeComponentBean.firstComboList}" .... />
</h:selectOneMenu>
<h:selectOneMenu
...
value="#{myCompositeComponentBean.secondComboValue}"
valueChangeListener="#{myCompositeComponentBean.bbb}">
<f:selectItem itemLabel="Choose one .." noSelectionOption="true" />
<f:selectItems value="#{myCompositeComponentBean.secondComboList}" .... />
</h:selectOneMenu>
And the composite component's JSF Bean will be like :
// this model will serve the composite component
@Named
@Scope("view")
public class MyCompositeComponentBean {
private String firstComboValue, secondComboValue;
private List<String> firstComboList, secondComboList;
...
}
This is an example of Page1.xhtml :
....
main department : <my:comboChainComponent /> <!-- 2 select items will be rendered here -->
secondary department : <my:comboChainComponent /> <!-- another 2 select items will be rendered here -->
....
And the Page1Bean (Main JSF Bean for Page1.xhtml)
@Named
@Scope("view")
public class Page1Bean {
// inject the first bean for the composite component 1
@Inject private MyCompositeComponentBean bean1;
@Inject private MyCompositeComponentBean bean2;
...
}
Is it possible to achieve this kind of reusability?
Thank you.
Why don't use this kind of approach.
<mytag:combo id="combo1"
value="#{bean.firstData}"
model="#{globalBean.getList()}"
update="form1:combo2" />
<mytag:combo id="combo2"
value="#{bean.secondData}"
model="#{globalBean.getSubList(bean.firstData)}" />
You can use composite attribute.
...
<composite:interface name="combo">
... define your attributes here
</composite:interface>
<composite:implementation>
<p:outputPanel id="content">
<p:selectOneMenu id="select_menu_1" value="#{cc.attrs.value}">
<f:selectItems value="#{cc.attrs.model}" />
<p:ajax event="change" process="@this" update="#{cc.attrs.update}" />
//add converter if you want
</p:selectOneMenu>
</p:outputPanel>
</composite:implementation>