了解SelectItemGroup

use*_*882 2 jsf renderer jsf-2 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
Run Code Online (Sandbox Code Playgroud)

RadioRenderer正在从标准public void encodeEnd(FacesContext context, UIComponent component)Renderer方法调用类中的 override .但是有以下代码:

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
        }
}
Run Code Online (Sandbox Code Playgroud)

所以,我通过这个例子尝试了它:

<h:selectOneRadio>
    <f:selectItem />
    <f:selectItems value="#{myBean.vals}" />
    <f:selectItems value="#{myBean.valss}" />
</h:selectOneRadio>
Run Code Online (Sandbox Code Playgroud)

并且selectItemselectItemses被视为不是实例SelectItemGroup.为此selectItem非常清楚,但我预计selectItems会映射到SelectItemGroup实例.

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

Bal*_*usC 5

它无法以声明方式创建.它只能以编程方式创建.的<f:selectItems>也支持List<SelectItem>javax.faces.model.SelectItem实例其中SelectItemGroup是一个子类.以下是其javadoc相关的摘录:

SelectItemGroup是一个子类,SelectItem用于标识一组选项,这些选项将作为从属"子菜单"或"选项列表"提供,具体取决于实际使用的UISelectManyUISelectOne渲染器的要求.通常,此实例的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);
}
Run Code Online (Sandbox Code Playgroud)
<f:selectItems value="#{bean.availableItems}" />
Run Code Online (Sandbox Code Playgroud)

在里面<h:selectOneRadio>它将呈现为嵌套表(这是恕我直言,一个糟糕的渲染,他们最好将组标签渲染为<thead>,但除此之外).当你设置layout为最佳时,它是最好的pageDirection,否则一切都会出现在一行(lineDirection)中.

<h:selectOneRadio layout="pageDirection">
    <f:selectItems value="#{bean.availableItems}" />
</h:selectOneRadio>
Run Code Online (Sandbox Code Playgroud)

使用SelectItemGroup <h:selectOneRadio>


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

<h:selectOneMenu>
    <f:selectItems value="#{bean.availableItems}" />
</h:selectOneMenu>
Run Code Online (Sandbox Code Playgroud)

使用SelectItemGroup <h:selectOneMenu>


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

<h:selectManyListbox>
    <f:selectItems value="#{bean.availableItems}" />
</h:selectManyListbox>
Run Code Online (Sandbox Code Playgroud)

使用SelectItemGroup <h:selectManyListbox>


<h:selectManyCheckbox>具有相同(语义别扭)嵌套表格渲染为<h:selectOneRadio>:

<h:selectManyCheckbox layout="pageDirection">
    <f:selectItems value="#{bean.availableItems}" />
</h:selectManyCheckbox>
Run Code Online (Sandbox Code Playgroud)

使用SelectItemGroup <h:selectManyCheckbox>


<h:selectManyMenu>根本没用,所以我会跳过它.

也可以看看: