【问题标题】:ActionListener not working properly with ViewScope?ActionListener 不能与 ViewScope 一起正常工作?
【发布时间】:2014-01-20 18:17:08
【问题描述】:

又是我,

自从使用action 切换到actionListener 后,我遇到了这个问题。这是一个奇怪的麻烦,我不知道为什么会这样。

当我试图从 PrimeFaces 数据表中删除一个项目时,我会得到 NullPointerException。但是,如果我先编辑那个项目然后再回来删除,就可以了!?

我正在使用 actionListener 在 JSF 中使用 Ajax。当我使用动作时,它仍然可以正常工作。

JSF 页面

<p:commandButton id="editButton" icon="ui-icon-pencil"
                 value="#{appBundle.Edit}"
                 action="detail.xhtml?faces-redirect=true">
    <f:setPropertyActionListener value="#{a}"
                                 target="#{academicManagedBean.academicSelected}"/>
</p:commandButton>
<p:commandButton id="deleteButton" icon="ui-icon-trash"
                 value="#{appBundle.Delete}"
                 actionListener="#{academicManagedBean.delete}"
                 update=":growl,datalist">
    <p:confirm header="Confirmation" message="Are you sure?" icon="ui-icon-alert" />
    <f:setPropertyActionListener value="#{a}"
                                 target="#{academicManagedBean.academicSelected}" />
</p:commandButton>
<p:confirmDialog global="true" showEffect="fade" hideEffect="explode">  
    <p:commandButton value="Yes" type="button"
                     styleClass="ui-confirmdialog-yes" icon="ui-icon-check"/>  
    <p:commandButton value="No" type="button"
                     styleClass="ui-confirmdialog-no" icon="ui-icon-close"/>       
</p:confirmDialog>

托管 Bean 类

@ManagedBean
@ViewScoped
public class AcademicManagedBean extends TblAcademic implements Serializable {

    private List<TblAcademic> all;
    private static TblAcademic academicSelected;

    public AcademicManagedBean() {
        super();
    }

    public List<TblAcademic> getAll() {
        try {
            all = new com.rdb.bll.AcademicBLL().getAll();
            return all;
        } catch (Exception ex) {
            Logger.getLogger(AcademicManagedBean.class.getName()).log(Level.SEVERE, null, ex);
            return null;
        }
    }

    public void add(ActionEvent actionEvent) throws Exception {
        boolean check = new com.rdb.bll.AcademicBLL().add(this);
        if (check) {
            JsfUtil.addSuccessMessage("Congratulation, new student has been added successfully!");
        } else {
            JsfUtil.addErrorMessage(ResourceBundle.getBundle("com.rdb.service.AppBundle").getString("PersistenceErrorOccured"));
        }
    }

    public void update(ActionEvent actionEvent) throws Exception {
        boolean check = new com.rdb.bll.AcademicBLL().update(AcademicManagedBean.academicSelected);
        if (check) {
            JsfUtil.addSuccessMessage("Congratulation, student has been updated successfully!");
        } else {
            JsfUtil.addErrorMessage(ResourceBundle.getBundle("com.rdb.service.AppBundle").getString("PersistenceErrorOccured"));
        }
    }

    public void delete(ActionEvent actionEvent) throws Exception {
        boolean check = new com.rdb.bll.AcademicBLL().delete(AcademicManagedBean.academicSelected);
        if (check) {
            JsfUtil.addSuccessMessage("Congratulation, student has been deleted successfully!");
        } else {
            JsfUtil.addErrorMessage(ResourceBundle.getBundle("com.rdb.service.AppBundle").getString("PersistenceErrorOccured"));
        }
    }

    public String studentDetail() {
        TblStudent std = new com.rdb.bll.StudentBLL().getById(AcademicManagedBean.academicSelected.getStudentRollNo());
        new StudentManagedBean().setStudentSelected(std);

        return "/backend/student/detail.xhtml?faces-redirect=true";
    }

    public String getClassNameById(int classId) {
        TblClass objClass = new com.rdb.bll.ClassBLL().getById(classId);
        return objClass.getClassName();
    }

    public TblAcademic getAcademicSelected() {
        return academicSelected;
    }

    public void setAcademicSelected(TblAcademic academicSelected) {
        AcademicManagedBean.academicSelected = academicSelected;
    }

我做错了吗?请帮我改正,谢谢。

【问题讨论】:

    标签: jsf-2 primefaces


    【解决方案1】:
    <p:commandButton id="deleteButton" icon="ui-icon-trash"
                     value="#{appBundle.Delete}"
                     actionListener="#{academicManagedBean.delete}"
                     update=":growl,datalist">
        <p:confirm header="Confirmation" message="Are you sure?" icon="ui-icon-alert" />
        <f:setPropertyActionListener value="#{a}"
                                     target="#{academicManagedBean.academicSelected}" />
    </p:commandButton>
    

    您正在actionListener 方法而不是操作方法中执行删除。这个不对。业务操作应在action 方法中执行。所有操作listeners,包括&lt;f:setPropertyActionListener&gt;,,都在action 方法之前调用,其顺序与在命令组件上声明和分配的顺序完全相同。因此,实际上,首先调用删除,然后设置属性。这就解释了为什么在删除期间该属性为空。

    解决方法很简单:使其成为真正的操作方法:

    <p:commandButton id="deleteButton" icon="ui-icon-trash"
                     value="#{appBundle.Delete}"
                     action="#{academicManagedBean.delete}"
                     update=":growl,datalist">
        <p:confirm header="Confirmation" message="Are you sure?" icon="ui-icon-alert" />
        <f:setPropertyActionListener value="#{a}"
                                     target="#{academicManagedBean.academicSelected}" />
    </p:commandButton>
    

    不要忘记删除 ActionEvent 参数:

    public void delete() {  
        // ...
    }
    

    本文摘自 JSF Guru Balcus 在此处Posted by JSF Guru 发布的答案

    【讨论】:

    • 我不明白。在详细信息页面或添加新页面中,我也在使用actionListener,它仍然可以正常工作。无论如何,您的解决方案解决了我的问题。谢谢你。
    猜你喜欢
    • 2018-11-10
    • 2014-07-01
    • 1970-01-01
    • 2016-07-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多