了解SelectItemGroup

时间:2015-08-09 15:33:27

标签: jsf jsf-2 renderer selectoneradio

深入研究RadioRenderer源代码我注意到以下事项:

方法

@Override
protected void renderOption(FacesContext context,
                            UIComponent component,
                            Converter converter,
                            SelectItem curItem,
                            Object currentSelections,
                            Object[] submittedValues,
                            boolean alignVertical,
                            int itemNumber,
                            OptionComponentInfo optionInfo) throws IOException
正在从标准RadioRenderer Renderer方法调用public void encodeEnd(FacesContext context, UIComponent component)类中的

overriden。但是有以下代码:

Iterator<SelectItem> items =
          RenderKitUtils.getSelectItems(context, component);
//some code
while (items.hasNext()) {
        SelectItem curItem = items.next();
        idx++;
        // If we come across a group of options, render them as a nested
        // table.
        if (curItem instanceof SelectItemGroup) {
             // do some
        else {
             // do another
        }
}

所以,我试过这个例子:

<h:selectOneRadio>
    <f:selectItem />
    <f:selectItems value="#{myBean.vals}" />
    <f:selectItems value="#{myBean.valss}" />
</h:selectOneRadio>

并且selectItemselectItems被视为SelectItemGroup的实例。对于selectItem非常清楚,但我希望selectItems将映射到SelectItemGroup实例。

你能不能澄清一下这件事吗?

1 个答案:

答案 0 :(得分:5)

无法以声明方式创建。它只能以编程方式创建。 <f:selectItems>还支持List<SelectItem> javax.faces.model.SelectItem个实例,其中SelectItemGroup是子类。以下是其javadoc

的相关摘录
  

SelectItemGroup SelectItem的子类,用于标识一组选项,这些选项将作为从属“子菜单”或“选项列表”提供,具体取决于{的要求实际使用的{3}}或UISelectMany渲染器。通常,此实例的value属性将被忽略,此实例的label属性将用于标记子菜单。

以下是如何创建它们的基本示例:

private List<SelectItem> availableItems; // +getter

@PostConstruct
public void init() {
    availableItems = new ArrayList<>();

    SelectItemGroup group1 = new SelectItemGroup("Group 1");
    group1.setSelectItems(new SelectItem[] {
        new SelectItem("Group 1 Value 1", "Group 1 Label 1"),
        new SelectItem("Group 1 Value 2", "Group 1 Label 2"),
        new SelectItem("Group 1 Value 3", "Group 1 Label 3")
    });
    availableItems.add(group1);

    SelectItemGroup group2 = new SelectItemGroup("Group 2");
    group2.setSelectItems(new SelectItem[] {
        new SelectItem("Group 2 Value 1", "Group 2 Label 1"),
        new SelectItem("Group 2 Value 2", "Group 2 Label 2"),
        new SelectItem("Group 2 Value 3", "Group 2 Label 3")
    });
    availableItems.add(group2);
}
<f:selectItems value="#{bean.availableItems}" />

UISelectOne内部,它将呈现为嵌套表格(恕我直言,这是一个糟糕的渲染,他们最好将组标签渲染为<thead>,但除此之外)。将layout设置为pageDirection时最明显,否则所有内容都会显示在一行(lineDirection)。

<h:selectOneRadio layout="pageDirection">
    <f:selectItems value="#{bean.availableItems}" />
</h:selectOneRadio>

<h:selectOneRadio>

<h:selectOneRadio> with SelectItemGroup内部,它将呈现为一个树,其中选项值嵌套在<optgroup>中(实际上是SelectItemGroup的主要用例):

<h:selectOneMenu>
    <f:selectItems value="#{bean.availableItems}" />
</h:selectOneMenu>

<h:selectOneMenu>

<h:selectOneMenu> with SelectItemGroup也支持它(<h:selectManyListbox>具有完全相同的渲染,但仅支持单个选择):

<h:selectManyListbox>
    <f:selectItems value="#{bean.availableItems}" />
</h:selectManyListbox>

<h:selectOneListbox>

<h:selectManyListbox> with SelectItemGroup具有与<h:selectOneRadio>相同的(语义上不好的)嵌套表格呈现:

<h:selectManyCheckbox layout="pageDirection">
    <f:selectItems value="#{bean.availableItems}" />
</h:selectManyCheckbox>

<h:selectManyCheckbox>

<h:selectManyCheckbox> with SelectItemGroup根本没用,所以我会跳过它。

另见: