При реализации пользовательского компонента Facelets, который расширяет некоторый существующий компонент, довольно часто ваш пользовательский компонент принимает те же атрибуты, что и расширяемый компонент.
Например, расширенный h: inputText может быть следующим:
<ui:composition>
<custom:decorate styleClass="input">
<h:inputText id="#{id}" value="#{value}" required="#{required}"
styleClass="#{styleClass}" disabled="#{disabled}" rendered="#{rendered}"
converterMessage="#{converterMessage}"
requiredMessage="#{requiredMessage}"
validatorMessage="#{validatorMessage}" onchange="#{onchange}"
style="#{style}">
<ui:insert/>
</h:inputText>
</custom:decorate></ui:composition>
Цель состоит в том, чтобы позволить клиенту компонента использовать расширенную версию так же, как расширяемый компонент.
В приведенном выше примере есть следующие пробелы:
- Атрибут id обязателен, передача без значения не приведет к автоматической генерации идентификатора.
- converterMessage, requiredMessage, validatorMessage, ... - почти так же, как атрибут 'id', эти атрибуты должны иметь особое значение, если они не предоставлены клиентом
- отключено, отображается и другие логические атрибуты - если клиент не предоставляет значение, тогда «# {attributeName}» преобразуется в «ложь».
- action и actionListener - для компонентов источника действия Facelet пытается оценить значение, указанное клиентом как «ValueExpression», а не как «MethodExpression».
Есть несколько простых простых решений (например, использовать c: if, c: когда и т. Д. Для обработки 1-3; передача bean-объекта и actionMethodName или реализовать компонент сопоставления действий для обработки 4), но когда количество атрибутов большой, код компонента превращается в адский код спагетти.
Может быть, для JSF 1.2 уже есть несколько твердых решений?
Мне также будет полезно увидеть ответ с хорошими идеями о том, как реализовать такое решение или его часть.