Составной компонент JSF и элементы выбора

#java #jsf-2 #composite-component

#java — язык #jsf-2 #составной компонент #java

Вопрос:

Я поиграл с составными компонентами и столкнулся с чем-то, чего не смог понять. Без использования составного компонента у меня было бы что-то вроде этого:

 <h:outputText value="Some Label:"/>
<h:selectOneMenu">
  <f:selectItem itemLabel="Item 1"/>
  <f:selectItem itemLabel="Item 2"/>
  <f:selectItem itemLabel="Item 3"/>
</h:selectOneMenu>
  

По сути, я превратил этот фрагмент в составной компонент:

 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:f="http://java.sun.com/jsf/core"  
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:composite="http://java.sun.com/jsf/composite">

  <!-- INTERFACE -->
  <composite:interface>
    <composite:attribute name="label" required="true"/>
    <composite:attribute name="options" required="true"/>      
  </composite:interface>

  <!-- IMPLEMENTATION -->          
  <composite:implementation>
    <h:outputText value="#{cc.attrs.label}"/>
    <h:selectOneMenu style="width:140px;">
        <f:selectItem value="#{cc.attrs.options}" />
    </h:selectOneMenu>  
  </composite:implementation>
</html>
  

Теперь вот где я в тупике. Я знаю, что мог бы поместить список элементов, которые я хочу использовать в компоненте, в вспомогательный компонент и использовать его следующим образом:

 <util:dropdown label="Some Label:" options="#{backingBean.list}"/>
  

Реальный вопрос заключается в том, есть ли способ передать параметры без необходимости использовать вспомогательный компонент? Я предполагаю, что что-то вроде:

 <util:dropdown label="Some Label:" options="Item 1, Item 2, Item 3"/>
  

или , может быть

 <util:dropdown label="Some Label:" options="#{backingBean.list}">
     <f:selectItem itemLabel="Item 1"/>
     <f:selectItem itemLabel="Item 2"/>
     <f:selectItem itemLabel="Item 3"/>
</util:dropdown>
  

Примечание: очевидно, что эти два варианта не работают, иначе я бы не задавал этот вопрос.

Ответ №1:

Реальный вопрос заключается в том, есть ли способ передать параметры без необходимости использовать вспомогательный компонент? Я предполагаю, что что-то вроде:

 <util:dropdown label="Some Label:" options="Item 1, Item 2, Item 3"/>
  

Вы можете использовать JSTL fn:split() , чтобы разделить их на String[] . <f:selectItems> Также принимает это как value . Я бы только убрал пробелы вокруг запятой в options атрибуте.

 xmlns:fn="http://java.sun.com/jsp/jstl/functions"
...

<h:selectOneMenu>
    <f:selectItems value="#{fn:split(cc.attrs.options, ',')}" />
</h:selectOneMenu> 
  

или, может быть

 <util:dropdown label="Some Label:">
    <f:selectItem itemLabel="Item 1"/>
    <f:selectItem itemLabel="Item 2"/>
    <f:selectItem itemLabel="Item 3"/>
</util:dropdown>
  

Вы можете использовать <composite:insertChildren> в составном компоненте для объявления местоположения, в которое должны быть вставлены дочерние элементы составного компонента.

 <h:selectOneMenu>
    <composite:insertChildren />
</h:selectOneMenu> 
  

Комментарии:

1. Допустим, что мне нужен составной компонент для вставки двух разных наборов дочерних элементов в двух разных местах — как бы я мог выполнить это иначе? Мне пришлось бы использовать только первый вариант. Я попытался поместить f:SelectItems в фасет, а затем отобразить этот фасет в составном компоненте, но это также не работает. В случае несоставного компонента, т. Е. просто используя ui: decorate, я могу указать несколько ui:defines для ui:вставить несколько дочерних элементов по имени. Почему составные компоненты не имеют этой функции?

2. @GreenieMeanie: составные файлы поддерживают фасеты.