问题
I have been searching a lot for a way to make a composite component similar to: <h:selectOneRadio />
but I did not succeed.
I want something like:
<myowntags:selectOneRadio>
<f:selectItem itemValue="value0" itemLabel="This is the value 0" />
<f:selectItem itemValue="value1" itemLabel="This is the value 1" />
<f:selectItem itemValue="value2" itemLabel="This is the value 2" />
</myowntags:selectOneRadio>
and:
<myowntags:selectOneRadio>
<f:selectItems value="#{controller.items}" />
</myowntags:selectOneRadio>
As you can see, I want this composite component to have a child: <f:selectItem />
and render it the way I want.
Thanks in advance.
回答1:
You could check and iterate over them by #{cc.children}
. The #{cc}
refers to the current composite UIComponent instance which in turn has a getChildren() method. You could do kind of an instanceof
check by checking the child's FQN (or simple name if that's sufficient) in the <cc:implementation>
:
<c:forEach items="#{cc.children}" var="child">
<c:set var="type" value="#{child['class'].simpleName}" />
<c:if test="#{type == 'UISelectItem'}">
<input type="radio" value="#{child.itemValue}" />#{child.itemLabel}<br/>
</c:if>
<c:if test="#{type == 'UISelectItems'}">
<c:forEach items="#{child.value}" var="item">
<input type="radio" value="#{item.value}" />#{item.label}<br/>
</c:forEach>
</c:if>
</c:forEach>
Your next problem is however collecting the submitted values. For that you'd need to implement the decode()
method in the backing UIComponent
which you reference by <cc:interface componentType>
. Or, better, create a custom UIComponent
with a Renderer
instead. Taking over the Renderer
's job in the view is clumsy.
来源:https://stackoverflow.com/questions/12509310/how-to-make-composite-component-similar-to-hselectoneradio