PrimeFaces p:ajax无法识别Facelet标记参数

时间:2012-05-21 19:49:05

标签: jsf-2 primefaces facelets glassfish-3

我有一个简单的Facelet标签:

<ui:composition>
  <ui:insert />
</ui:composition>

用于避免声明多个c:set标记 假设我在名为view的facelets taglib库中注册了它,并按照以下方式使用它:

<my:view bean="#{myController}">
  <p:inputText value="#{bean.value}>
    <p:ajax event="blur" process="@this" listener="#{bean.handleValueChanged}" />
  </p:inputText>
</my:view>

属性value完全由p:inputText解析,但p:ajax会抛出此内容:

Target Unreachable, identifier 'bean' resolved to null
javax.el.PropertyNotFoundException: Target Unreachable, identifier 'bean' resolved to null
    at com.sun.el.parser.AstValue.getTarget(AstValue.java:153)
    at com.sun.el.parser.AstValue.invoke(AstValue.java:237)
    at com.sun.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:302)
    at org.jboss.weld.util.el.ForwardingMethodExpression.invoke(ForwardingMethodExpression.java:39)
    at org.jboss.weld.el.WeldMethodExpression.invoke(WeldMethodExpression.java:50)
    at org.primefaces.component.behavior.ajax.AjaxBehaviorListenerImpl.processAjaxBehavior(AjaxBehaviorListenerImpl.java:47)

这是一个错误还是预期的行为?

更新: 我只是用f:ajax做了同样的尝试!

不过,环境如下:
Glassfish 3.1.2
PF 3.0,3.2,3.3

UPDATE2
RichFaces与{{1}}的问题完全相同。似乎就像PrimeFaces的bug(我今天会在PF bug跟踪器上发布一个问题)。

2 个答案:

答案 0 :(得分:4)

我的同事刚刚提供了一个补丁来解决这个问题。

AjaxBehaviorListenerImpl#processAjaxBehaviour的当前实施如下:

public void processAjaxBehavior(AjaxBehaviorEvent event) throws AbortProcessingException {
        FacesContext context = FacesContext.getCurrentInstance();
        final ELContext elContext = context.getELContext();

        try{
            listener.invoke(elContext, new Object[]{});
        } catch (MethodNotFoundException mnfe) {
            MethodExpression argListener = context.getApplication().getExpressionFactory().
                        createMethodExpression(elContext, listener.getExpressionString(), null, new Class[]{event.getClass()});

            argListener.invoke(elContext, new Object[]{event});
        }
    }

他建议像这样调整它:

import javax.faces.view.facelets.FaceletContext;

public void processAjaxBehavior(AjaxBehaviorEvent event) throws AbortProcessingException {
        FacesContext context = FacesContext.getCurrentInstance();
        final ELContext elContext = context.getELContext();

        try{
            listener.invoke(elContext, new Object[]{});
        } catch (MethodNotFoundException mnfe) {
            FaceletContext fc = (FaceletContext) context.getAttributes().get(FaceletContext.FACELET_CONTEXT_KEY);
            MethodExpression argListener = context.getApplication().getExpressionFactory().
                        createMethodExpression(fc, listener.getExpressionString(), null, new Class[]{ event.getClass() });

            argListener.invoke(elContext, new Object[]{ event });
        }
    }

希望这将得到PF团队的批准。

答案 1 :(得分:-1)

调整不适用于我的用例,它比单个ui更复杂:include。

<c:forEach items="#{items}" var="item">
            <ui:include src="#{item.uri}">
                <ui:param name="itemBean" value="#{item.bean}"/>
            </ui:include>

</c:forEach>

我认为必须在新的MethodExpression

中重用侦听器的变量映射器