У меня есть простой составной компонент с дополнительным слушателем ajax, реализованным с помощью компонента richfaces a4j: ajax.
Вот определение интерфейса:
<!-- INTERFACE -->
<composite:interface name="inplaceInput">
<composite:attribute name="value" required="true" />
<composite:attribute name="render" default="@this" />
<composite:attribute name="ajaxListener" method-signature="void actionListener(javax.faces.event.AjaxBehaviorEvent)" />
</composite:interface>
Следующий код отлично работает, используя два дублированных блока с противоположным условием рендеринга:
<composite:implementation>
<rich:inplaceInput value="#{cc.attrs.value}" rendered="#{!empty cc.attrs.ajaxListener}">
<a4j:ajax event="change" render="#{cc.attrs.render}" execute="@this" listener="#{cc.attrs.ajaxListener}" />
</rich:inplaceInput>
<rich:inplaceInput value="#{cc.attrs.value}" rendered="#{empty cc.attrs.ajaxListener}">
<a4j:ajax event="change" render="#{cc.attrs.render}" execute="@this" />
</rich:inplaceInput>
</composite:implementation>
Но я бы хотел избежать дублирования, потому что мой компонент намного сложнее ...
Использовать условие рендеринга на a4j: ajax было моей первой идеей:
<rich:inplaceInput value="#{cc.attrs.value}">
<a4j:ajax event="change" render="#{cc.attrs.render}" execute="@this" listener="#{cc.attrs.ajaxListener}" rendered="#{!empty cc.attrs.ajaxListener}" />
<a4j:ajax event="change" render="#{cc.attrs.render}" execute="@this" rendered="#{empty cc.attrs.ajaxListener}" />
</rich:inplaceInput>
Но это не работает, и ошибка весьма неясна:
javax.faces.FacesException: Unable to resolve composite component from using page using EL expression '#{cc.attrs.ajaxListener}'
at com.sun.faces.facelets.tag.TagAttributeImpl$AttributeLookupMethodExpression.invoke(TagAttributeImpl.java:444)
at org.ajax4jsf.component.behavior.MethodExpressionAjaxBehaviorListener.processAjaxBehavior(MethodExpressionAjaxBehaviorListener.java:73)
Я пытался с обработчиком c: if, потому что дерево не должно иметь оба компонента:
<rich:inplaceInput value="#{cc.attrs.value}">
<c:if test="#{!empty cc.attrs.ajaxListener}">
<a4j:ajax event="change" render="#{cc.attrs.render}" execute="@this" listener="#{cc.attrs.ajaxListener}" />
</c:if>
<c:if test="#{empty cc.attrs.ajaxListener}">
<a4j:ajax event="change" render="#{cc.attrs.render}" execute="@this" />
</c:if>
</rich:inplaceInput>
А затем получил еще одну ошибку (используя ajaxListener = "# {itemList.updateValue}"):
javax.el.PropertyNotFoundException: /pages/itemList.xhtml @71,81 ajaxListener="#{itemList.updateValue}": Property 'updateValue' not found on type com...ItemListManager
Если бы атрибут был EL, возвращающим значение, я мог бы проверить значение по умолчанию. Я также мог бы добавить логический атрибут, чтобы узнать, установлен ли слушатель ... Или добавить метод по умолчанию для компонента componentType, который ничего не делает ... Но это не очень красиво ...
Как проверить, установлен ли атрибут без доступа к его значению или привязке метода?
Заранее спасибо за любую идею,
Rgds,
FM