2

深入研究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从标准 public void encodeEnd(FacesContext context, UIComponent component)Renderer 方法调用类中的覆盖。但是有以下一段代码:

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>

并且 theselectItemselectItemses 被视为不是SelectItemGroup. 因为selectItem这非常清楚,但我希望这selectItems会映射到SelectItemGroup实例。

你就不能稍微澄清一下吗?

4

1 回答 1

7

它不能以声明方式创建。它只能以编程方式创建。<f:selectItems>还支持List<SelectItem>是子类的javax.faces.model.SelectItem实例SelectItemGroup。以下是其javadoc相关性的摘录:

SelectItemGroupSelectItem标识一组选项的子类,这些选项将作为从属“子菜单”或“选项列表”提供,具体取决于实际使用的渲染器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);
}
<f:selectItems value="#{bean.availableItems}" />

<h:selectOneRadio>它内部将呈现为嵌套表(恕我直言,这是一个糟糕的呈现,他们最好将组标签呈现为 a <thead>,但除此之外)。layout当您设置为时,它最清晰可见pageDirection,否则所有内容都将出现在一行 ( lineDirection) 中。

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

<h:selectOneRadio> 与 SelectItemGroup


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

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

<h:selectOneMenu> 与 SelectItemGroup


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

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

<h:selectManyListbox> 与 SelectItemGroup


具有与以下<h:selectManyCheckbox>相同(语义上尴尬)的嵌套表渲染<h:selectOneRadio>

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

<h:selectManyCheckbox> 与 SelectItemGroup


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

也可以看看:

于 2015-08-10T07:07:01.517 回答