Как сделать составной компонент похожим на <h: selectOneRadio/">

Я много искал способ создания составного компонента: <h:selectOneRadio /> но мне это не удалось.

Мне нужно что-то вроде:

<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>

и

<myowntags:selectOneRadio>
  <f:selectItems  value="#{controller.items}"  />
</myowntags:selectOneRadio>

Как вы можете видеть, я хочу, чтобы этот составной компонент имел дочерний элемент: <f:selectItem /> и отображал его так, как я хочу.

Спасибо заранее.

Ответ 1

Вы можете проверить и перебрать их на #{cc.children}. #{cc} относится к текущему составному экземпляру UIComponent, который, в свою очередь, имеет getChildren(). Вы можете сделать проверку instanceof, проверив дочернее FQN (или простое имя, если это достаточно) в <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>

Ваша следующая проблема, однако, собирает представленные значения. Для этого вам понадобится реализовать метод decode() в резервной копии UIComponent, которую вы ссылаетесь на <cc:interface componentType>. Или, лучше, создайте пользовательский UIComponent с Renderer. Выполнение задания Renderer в представлении неудобно.