JSF2复合组件 - 方法属性existenc的条件

Flo*_*ian 5 rendered-attribute composite-component jsf-2

我有一个简单的复合组件,带有一个可选的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>
Run Code Online (Sandbox Code Playgroud)

以下代码使用两个具有相反呈现条件的重复块正常工作:

<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>
Run Code Online (Sandbox Code Playgroud)

但是我想避免重复,因为我的组件要复杂得多......

在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>
Run Code Online (Sandbox Code Playgroud)

但它不起作用,错误很明显:

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)
Run Code Online (Sandbox Code Playgroud)

我尝试使用ac:if handler,因为树不需要同时包含两个组件:

<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>
Run Code Online (Sandbox Code Playgroud)

然后又出现了另一个错误(使用ajaxListener ="#{itemList.updateValue}"):

javax.el.PropertyNotFoundException: /pages/itemList.xhtml @71,81 ajaxListener="#{itemList.updateValue}": Property 'updateValue' not found on type com...ItemListManager
Run Code Online (Sandbox Code Playgroud)

如果属性是EL返回值,我可以测试默认值.我还可以添加一个布尔属性来判断是否设置了监听器......或者在componentType bean上添加一个默认方法,什么都不做......但那不是很好......

如何在不访问其值或方法绑定的情况下测试是否设置了属性?

提前感谢任何想法,

RGDS,

调频

小智 5

您可以cc.getValueExpression()UIComponent类中使用,它将检查是否在复合组件的using页面中定义了Value Expression,如下所示:

<c:if test="#{!empty cc.getValueExpression('ajaxListener')}">     
  <a4j:ajax event="change" render="#{cc.attrs.render}" execute="@this" listener="#{cc.attrs.ajaxListener}" />     
</c:if> 
Run Code Online (Sandbox Code Playgroud)