ActionListener不会在复合组件中触发

时间:2013-02-25 13:55:07

标签: jsf jsf-2 composite-component

我有一个关于将ActionListener委托给复合组件(jsf)的具体问题。 我创建了一个复合组件来显示(浏览)和编辑任何个人用户数据(属性“user”)。

    <body>
        <co:interface>
            <co:attribute name="editAction"     required="false"  targets="edit"   method-signature="java.lang.String f()"/>
            <co:attribute name="saveAction"     required="false"  targets="save"   method-signature="java.lang.String f()"/>
            <co:attribute name="cancelAction"   required="false"  targets="cancel" method-signature="java.lang.String f()"/>
            <co:attribute name="isBrowseModus"  required="true"/>
            <co:attribute name="user"           required="true"/>
            <co:attribute name="isDeveloper"    required="true"/>
            <co:actionSource name="edit"/>
            <co:actionSource name="save"/>
            <co:actionSource name="cancel"/>
        </co:interface>
............
        <p:inplace id="inpLand" editor="true" 
            toggleable="#{not cc.attrs.isBrowseModus}" 
            style="#{cc.attrs.isBrowseModus ? 'color: black' : 'color: blue'}">  
                <p:inputText value="#{cc.attrs.user.land}" label="text"/>  
        </p:inplace>  
...........
       <c:if test="#{cc.attrs.isBrowseModus}">
         <h:commandButton id="edit" value="Edit"/>
       </c:if>
........

实际上,这个复合组件是由调用 myData.xhtml 的视图调用的:

        <ui:define name="center">
            <h3>MyData Developer </h3>
            <h4>Welcomne</h4>
            <h:form id="dataForm">  
                <mc:UserData user="#{dataBean.user}" isDeveloper="#{dataBean.developer}" isBrowseModus="#{dataBean.browseModus}" cancelAction="#{dataBean.cancel}" 
saveAction="#{dataBean.save}" editAction="#{dataBean.edit}">
                    <f:actionListener for="edit" binding="#{dataBean.editActionListener}"/>
                </mc:UserData>   
            </h:form>  
        </ui:define>
    </ui:composition>

在复合组件中有一个(id = edit),并且传递的actionListener(请参阅myData中的f:actionListener)应绑定到此commandButton(id = edit)。这是我在阅读不同的论坛讨论和几个文件后的理解。

不幸的是,在单击编辑按钮后,editActionListener方法没有激活,我不知道为什么。 当然,这个 editActionListener 方法存在于managedBean“dataBean”(myData.java)中:

public void editActionListener(ActionEvent ae) {
    browseModus = false;
    FacesContext.getCurrentInstance().renderResponse();
}    

我的目标是什么: 在该复合组件中,用户可以通过单击“编辑”按钮来更改任何用户数据。我更喜欢使用PRIMEFACES的inplace标签。单击编辑按钮后,所有可更改字段都应显示为蓝色。

我的问题:

  1. 有人可以解释为什么有界的editActionListener方法 不解雇?
  2. 一般来说,这是设置的正确方法 “isBrowseModus”属性(单击编辑按钮后为false)?或者是否有更方便的方法来实现这一结果?
  3. 我正在使用primefaces,首先我尝试使用p:commandButton, 但不幸的是它不起作用。使用p:commandButton时,单击编辑按钮后会出现异常。 JSF找不到 我的managedBean中的editActionListener方法 (PropertyNotFoundException)?!?!?
  4. 任何帮助都会受到赞赏。提前谢谢了。 问候, 博多

1 个答案:

答案 0 :(得分:1)

根据tag documentation<f:actionListener binding>必须引用实现ActionListener接口的具体实例,而不是方法表达式。

总而言之,您可以通过getter提供ActionListener接口的具体实现来解决您的问题,而getter又会调用所需的动作侦听器方法。

private ActionListener editActionListener = new ActionListener() {
    @Override
    public void processAction(ActionEvent event) throws AbortProcessingException {
        DataBean.this.editActionListener(event);
    }
};

public ActionListener getEditActionListener() {
    return editActionListener;
}

public void editActionListener(ActionEvent event) {
    browseModus = false;
    FacesContext.getCurrentInstance().renderResponse();
}

然而这很笨拙,这表明你正在寻找可能出错方向的解决方案。更简单的方法是使用<cc:attribute targets="edit">代替。

<cc:interface>
    ...
    <cc:attribute name="actionListener" targets="edit" />
</cc:interface>

用作

<mc:UserData ... actionListener="#{dataBean.editActionListener}" />