1

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

    <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)。这是我在阅读了不同的论坛讨论和几个文档后的理解。

不幸的是,单击 Edit-Button 后 editActionListener 方法没有触发,我不知道为什么。当然,这个editActionListener方法存在于 managedBean“dataBean”(myData.java)中:

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

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

我的问题:

  1. 谁能解释我为什么没有触发有界的 editActionListener 方法?
  2. 通常,这是设置“isBrowseModus”属性(单击编辑按钮后为 false)的正确方法吗?或者有没有更方便的方法来实现这个结果?
  3. 我正在使用 primefaces,首先我尝试使用 p:commandButton ,但不幸的是它不起作用。使用 p:commandButton 时,单击编辑按钮后发生异常。JSF 在我的 managedBean (PropertyNotFoundException) 中找不到 editActionListener 方法?!?!?

任何帮助将不胜感激。提前谢谢了。问候, 博多

4

1 回答 1

2

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

总而言之,您的问题可以ActionListener通过通过 getter 提供接口的具体实现来解决,该 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}" />
于 2013-02-25T17:18:24.870 回答