"Составьте композит, Компонент" является JSF 2.x / конкретный термин Facelets для reuseable компонентов UI, которые объявляются с помощью чистого XML, а не Java. Составные теги определения XML компонента доступны под пространством имен 'http://xmlns.jcp.org/jsf/composite'.

“Составьте композит, Компонент” является JSF 2.x / конкретный термин Facelets для reuseable компонентов UI, которые объявляются с помощью чистого XML, а не Java. Составные теги определения XML компонента доступны под пространством имен http://xmlns.jcp.org/jsf/composite. Перед JSF 2.2, пространством имен http://java.sun.com/jsf/composite должен использоваться вместо этого.

Создание составных компонентов

Подготовьте структуру каталогов

Сначала создайте каталог resources в общественности webcontent (там, где WEB-INF каталог и все регулярные файлы Facelets также).

WebContent |-- WEB-INF | `-- lib |-- resources <--- `-- test.xhtml 

JSF 2.2 и позже позволяет изменять каталог с ресурсами путем определения названного параметра javax.faces.WEBAPP_RESOURCES_DIRECTORY в файле . Может быть разумно изменить каталог на, например, /WEB-INF/resources, начиная с файлов под /WEB-INF не читаемы через HTTP.

В каталоге с ресурсами создайте каталог исключительно для составных компонентов. Имя каталога заканчивается как дополнительный путь в составном пространстве имен компонента URI. Вы свободны выбрать имя. Мы возьмем mycomponents как пример.

WebContent |-- WEB-INF | `-- lib |-- resources | `-- mycomponents <--- `-- test.xhtml 

Таким образом, составные компоненты в этом каталоге доступны во всех шаблонах следующим пространством имен:

<html xmlns:my="http://xmlns.jcp.org/jsf/composite/mycomponents"> 

Префикс my свободно к Вашему выбору. http://xmlns.jcp.org/jsf/composite/ часть обязательна. mycomponents часть должна быть все равно как имя каталога.

Как Привет Мир составляет пример компонента, мы создадим составной компонент, который показывает простой счет оценки со звездами. Мы должны создать новый файл XHTML. Имя файла становится составным именем тега компонента. Вы свободны выбрать имя. Давайте назовем его rating.xhtml.

WebContent |-- WEB-INF | `-- lib |-- resources | `-- mycomponents | `-- rating.xhtml <--- `-- test.xhtml 

Таким образом, составной компонент доступен во всех шаблонах следующим образом:

<my:rating /> 

Создайте составной компонент

Вот то, как основной составной шаблон компонента похож. Вставьте это rating.xhtml.

<ui:component xmlns="http://www.w3.org/1999/xhtml" xmlns:f="http://xmlns.jcp.org/jsf/core" xmlns:h="http://xmlns.jcp.org/jsf/html" xmlns:ui="http://xmlns.jcp.org/jsf/facelets" xmlns:cc="http://xmlns.jcp.org/jsf/composite" > <cc:interface> <!-- Define component attributes here --> </cc:interface> <cc:implementation> <!-- Define component body here --> </cc:implementation> </ui:component> 

Мы хотели бы определить следующие атрибуты:

  • score, целое число, требуемое. Звездообразный счет.
  • maxScore, целое число, дополнительные, 100 по умолчанию. Максимальный возможный счет.
  • totalStars, целое число, дополнительные, 10 по умолчанию. Общая сумма звезд для отображения.

Теперь, вот то, как заключительная реализация похожа. Обратите внимание, что атрибуты доступны #{cc.attrs.attributename}.

<ui:component xmlns="http://www.w3.org/1999/xhtml" xmlns:f="http://xmlns.jcp.org/jsf/core" xmlns:h="http://xmlns.jcp.org/jsf/html" xmlns:cc="http://xmlns.jcp.org/jsf/composite" xmlns:ui="http://xmlns.jcp.org/jsf/facelets" xmlns:c="http://xmlns.jcp.org/jsp/jstl/core" xmlns:fn="http://xmlns.jcp.org/jsp/jstl/functions" > <cc:interface> <cc:attribute name="score" type="java.lang.Integer" required="true" /> <cc:attribute name="maxScore" type="java.lang.Integer" default="100" /> <cc:attribute name="totalStars" type="java.lang.Integer" default="10" /> </cc:interface> <cc:implementation> <c:set var="filled" value="#{fn:substringBefore(cc.attrs.score / (cc.attrs.maxScore / cc.attrs.totalStars), '.')}" /> <span style="font-size: 1.5em;"> <c:forEach begin="1" end="#{cc.attrs.totalStars}" varStatus="loop"> <h:outputText value="&#9733;" rendered="#{loop.index le filled}" /> <h:outputText value="&#9734;" rendered="#{loop.index gt filled}" /> </c:forEach> </span> </cc:implementation> </ui:component> 

Вот то, как можно использовать его в test.xhtml:

<!DOCTYPE html> <html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:f="http://xmlns.jcp.org/jsf/core" xmlns:h="http://xmlns.jcp.org/jsf/html" xmlns:ui="http://xmlns.jcp.org/jsf/facelets" xmlns:my="http://xmlns.jcp.org/jsf/composite/mycomponents" > <h:head> <title>Rating composite component demo</title> </h:head> <h:body> <my:rating score="60" /><br /> <my:rating score="5" maxScore="10" /><br /> <my:rating score="80" totalStars="5" /><br /> </h:body> </html> 

Вот то, как результат должен быть похожим (только если Ваша поддержка браузера звездообразные шрифты Unicode; Вы свободны заменить их реальными изображениями или даже представить половину звезды, которая, к сожалению, не доступна в Unicode):

★★★★★★☆☆☆☆

★★★★★☆☆☆☆☆

★★★★☆

Создайте отступающий компонент

Вышеупомянутая реализация имеет один недостаток, должный использовать использование JSTL <c:forEach> : как выполнения JSTL в течение времени изготовления представления вместо времени рендеринга представления, вышеупомянутая реализация не может использоваться в повторяющемся компоненте такой как <h:dataTable> или <ui:repeat>. Мы хотели бы использовать <ui:repeat> вместо этого, но это не поддерживает begin и end атрибуты. Таким образом, мы хотели бы присоединить некоторый код Java так, чтобы он преобразовал totalStars к пустому объектному массиву точно, что размер так, чтобы это могло использоваться в value атрибут. Идеально, это было бы сделано с помощью функции EL, но в целях изучения/Wiki мы будем использовать так называемый "компонент поддержки" вместо этого.

Для создания такого компонента поддержки мы должны создать класс, который расширяется UINamingContainer или по крайней мере реализации NamingContainer и возвраты UINamingContainer.COMPONENT_FAMILY в getFamily() метод. Вот основной шаблон:

package com.example; import javax.faces.component.FacesComponent; import javax.faces.component.UINamingContainer; @FacesComponent("myCompositeComponent") public class MyCompositeComponent extends UINamingContainer { // ... } 

Отметьте значение @FacesComponent атрибут. Это - то, которое необходимо указать в componentType атрибут <cc:interface> тег:

<cc:interface componentType="myCompositeComponent"> 

Таким образом, экземпляр отступающего компонента будет использоваться позади #{cc} переменная вместо этого. Это предлагает Вам возможность определить методы получателя и методы действия как value="#{cc.items}", action="#{cc.doSomething}" и так далее. Весь из <cc:attribute> attribues доступны в отступающем компоненте наследованным UIComponent#getAttributes() метод, который обеспечивает легкий доступ к атрибутам.

Поскольку наша оценка составляет компонент, отступающая реализация компонента должна быть похожей на это:

package com.example; import javax.faces.component.FacesComponent; import javax.faces.component.UINamingContainer; @FacesComponent("ratingComponent") public class RatingComponent extends UINamingContainer { public Object[] getItems() { Object totalStars = getAttributes().get("totalStars"); int size = Integer.valueOf(String.valueOf(totalStars)); return new Object[size]; } } 

И вот то, как rating.xhtml должен теперь быть похожим:

<ui:component xmlns="http://www.w3.org/1999/xhtml" xmlns:f="http://xmlns.jcp.org/jsf/core" xmlns:h="http://xmlns.jcp.org/jsf/html" xmlns:cc="http://xmlns.jcp.org/jsf/composite" xmlns:ui="http://xmlns.jcp.org/jsf/facelets" xmlns:c="http://xmlns.jcp.org/jsp/jstl/core" xmlns:fn="http://xmlns.jcp.org/jsp/jstl/functions" > <cc:interface componentType="ratingComponent"> <cc:attribute name="score" type="java.lang.Integer" required="true" /> <cc:attribute name="maxScore" type="java.lang.Integer" default="100" /> <cc:attribute name="totalStars" type="java.lang.Integer" default="10" /> </cc:interface> <cc:implementation> <c:set var="filled" value="#{fn:substringBefore(cc.attrs.score / (cc.attrs.maxScore / cc.attrs.totalStars), '.')}" /> <span style="font-size: 1.5em;"> <ui:repeat value="#{cc.items}" varStatus="loop"> <h:outputText value="&#9733;" rendered="#{loop.index lt filled}" /> <h:outputText value="&#9734;" rendered="#{loop.index ge filled}" /> </ui:repeat> </span> </cc:implementation> </ui:component> 

Отметьте value="#{cc.items}" в вышеупомянутом примере. Это в основном звонит getItems() метод на экземпляре отступающего компонента. Также обратите внимание, что мы избавились от JSTL <c:forEach>, таким образом, вышеупомянутое будет работать правильно в повторении компонент JSF такой как <ui:repeat>, <h:dataTable> и так далее.

<h:dataTable value="#{bean.products}" var="product"> <h:column>#{product.name}</h:column> <h:column><my:rating score="#{product.rating}" /></h:column> </h:dataTable> 

Ресурсы онлайн:

Связанные страницы информации о теге: