自定义jsf ui组件来替换<f:selectitems>

时间:2016-06-07 08:14:39

标签: jsf-2

我一直在尝试为jsf创建一个自定义ui组件来替换<f:selectItems />,它包含在selectOneMenu中。所以我的facesComponent需要生成所有选项,而selectOneMenu提供<select></select>

问题是选项不会在selectOneMenu中呈现,而是在其外部呈现。

我的facesComponent看起来像这样:

@FacesComponent(value = "be.mokuril.jsf.SelectItemsForEnum")
public class SelectItemsForEnum extends UISelectItems {

@Override
public void encodeAll(FacesContext facesContext) throws IOException {
    ResponseWriter responseWriter = ResponsefacesContext.getResponseWriter();
    responseWriter.startElement("option", null);
    responseWriter.writeAttribute("value", 1, null);
    responseWriter.write("option1");
    responseWriter.endElement("option");
    responseWriter.startElement("option", null);
    responseWriter.writeAttribute("value", 2, null);
    responseWriter.write("option2");
    responseWriter.endElement("option");
}

这是我的taglib:

<facelet-taglib xmlns="http://java.sun.com/xml/ns/javaee" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
version="2.0" id="mw"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facelettaglibrary_2_0.xsd" 
>
<namespace>http://www.mokuril.be/jsf/mw</namespace>
<composite-library-name>mw</composite-library-name>

<tag>
    <tag-name>selectItemsForEnum</tag-name>
    <component>
        <component-type>be.mokuril.jsf.SelectItemsForEnum</component-type>
    </component>
</tag>

而xhtml重现了这个问题:

<h:form>
 <h:selectOneMenu>
    <mw:selectItemsForEnum />
 </h:selectOneMenu>
</h:form>

我也在查看组件树:

<HtmlSelectOneMenu disabled="false" id="j_idt7" immediate="false" inView="true" localValueSet="false" readonly="false" rendered="true" required="false" transient="false" valid="true">
  <SelectItemsForEnum id="j_idt8" inView="true" rendered="true"  transient="false"/>
</HtmlSelectOneMenu>

如果我使用<f:selectItems />代替我的组件,我会得到这个:

<UISelectItems id="j_idt9" inView="true" rendered="true" transient="false"/>

这实际上是我的预期,但我显然必须忽略一些重要的事情。

1 个答案:

答案 0 :(得分:1)

您的具体问题是由于UISelectOne / UISelectMany组件会扫描其直接子项进行UISelectItem(s)次侮辱而导致的。当您使用复合组件时,其内容基本上包含在UIPanel组件中,该组件不是UISelectItem(s)的实例,因此选择组件将忽略它。从技术上讲,您应该使用自定义组件而不是复合组件。另请参阅When to use <ui:include>, tag files, composite components and/or custom components?

然而,您会遇到下一个问题:UISelectOne / UISelectMany将继续自行渲染选项并忽略渲染器的输出。基本上,没有一个<f:xxx>组件自己呈现HTML。此责任由其<h:xxx>父母负责。从技术上讲,如果您想操纵<h:selectOneMenu>的输出,则应该覆盖<f:selectItem(s)>的渲染器。

这是unclear你试图以这种方式解决的问题,但是如果我做了有根据的猜测,这些问题应该最有可能以正确的方式回答并解决你的真正的问题:How to use enum values in f:selectItem(s)和/或How to add tooltip to f:selectItems