ActionListener与ViewScope无法正常工作?

时间:2014-01-20 18:17:08

标签: jsf-2 primefaces

再次是我,

自从使用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;
    }

我做错了什么吗?请帮我纠正,谢谢你。

1 个答案:

答案 0 :(得分:2)

<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(包括<f:setPropertyActionListener>,)都在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

发布的答案