Составной компонент JSF2 - условие на наличие атрибута метода - PullRequest
5 голосов
/ 20 июля 2011

У меня есть простой составной компонент с дополнительным слушателем 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

1 Ответ

5 голосов
/ 17 февраля 2012

Вы можете использовать cc.getValueExpression() из UIComponent класса, который проверит, определено ли выражение значения на странице использования вашего составного компонента, например:

<c:if test="#{!empty cc.getValueExpression('ajaxListener')}">     
  <a4j:ajax event="change" render="#{cc.attrs.render}" execute="@this" listener="#{cc.attrs.ajaxListener}" />     
</c:if> 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...