2

我正在为小型 CRUD 应用程序使用 @ViewScoped Bean 我有一个编辑和查看页面,但是当我单击按钮(编辑)时,它将呈现编辑表单。编辑表单出现后,保存按钮或取消按钮不会调用该函数,而是呈现整个页面。actionListener 的函数根本没有被调用,一切都被初始化了。我的 bean 和页面有问题吗?我正在使用带有richfaces 和facelet 的JSF 2。

          //ViewScoped Bean   

            /*
     * To change this template, choose Tools | Templates
     * and open the template in the editor.
     */
    package com.legendMgr.Legend;

    import java.io.Serializable;
    import java.sql.SQLException;
    import java.util.List;


    import java.util.logging.Logger;
    import javax.annotation.PostConstruct;

    import javax.faces.application.FacesMessage;
    import javax.faces.bean.ManagedBean;
    import javax.faces.bean.ViewScoped;

import javax.faces.context.FacesContext;

/**
 *
 * @author kitex
 */
@ManagedBean(name = "legendbean")
@ViewScoped
public class LegendController implements Serializable {

    LegendDTO legendDTO;
    String selectedLegend;
    List<LegendDTO> legendDTOs;
    boolean edit;

    public List<LegendDTO> getLegendDTOs() {
        return legendDTOs;
    }

    public void setLegendDTOs(List<LegendDTO> legendDTOs) {
        this.legendDTOs = legendDTOs;
    }

    @PostConstruct
    void initialiseSession() {
        FacesContext.getCurrentInstance().getExternalContext().getSession(true);
    }

    public LegendController() {
        if (!edit) {
            legendDTO = new LegendDTO();
            legendDTO.getList().add(new Legend());
            legendDTOs = getLegends();
        }
    }


    public String getSelectedLegend() {
        return selectedLegend;
    }

    public void setSelectedLegend(String selectedLegend) {
        this.selectedLegend = selectedLegend;
    }

    public boolean isEdit() {
        return edit;
    }

    public void setEdit(boolean edit) {
        this.edit = edit;
    }

    public LegendDTO getLegendDTO() {
        return legendDTO;
    }

    public void setLegendDTO(LegendDTO legendDTO) {
        this.legendDTO = legendDTO;
    }

    public void addLegendRange() {
        Logger.getLogger(LegendController.class.getName()).warning("List Size " + legendDTO.getList().size());
        legendDTO.getList().add(new Legend());
        Logger.getLogger(LegendController.class.getName()).warning("List Size " + legendDTO.getList().size());

    }

    public void removeLegendRange(Legend legend) {
        if (legendDTO.getList().size() != 1) {
            legendDTO.getList().remove(legend);
        }
    }

    public String saveLegend() {
        Logger.getLogger(LegendController.class.getName()).warning("Save Legend Edit" + edit);
        LegendDAO dao = new LegendDAO();
        if (dao.addLegend(legendDTO, edit)) {
            edit = false;
            Logger.getLogger(LegendController.class.getName()).warning("Save Legend Edit" + edit);
        } else {

            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage("Could Not Save Confim if you have already defined Legend " + legendDTO.getLegendName() + "!"));
        }
        return "";
    }

    public String cancel() {
        edit = false;
        legendDTO = new LegendDTO();
        legendDTO.getList().add(new Legend());
         return "";
    }

    public List<LegendDTO> getLegends() {
        LegendDAO dao = new LegendDAO();
        return dao.getLegendDTO();
    }

    //All function from here are for legend  delete
    public void deleteLegendType(LegendDTO dto) {
        LegendDAO dao = new LegendDAO();
        if (dao.deleteLegendType(dto.getLegendName())) {
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage("Deleted !"));
        } else {
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage("Deleted Error !"));
        }
    }

    //All function from here is to legend edit
    public void editLegendType(LegendDTO dto) {
        edit = true;
        Logger.getLogger(LegendController.class.getName()).warning("DTO : " + dto.legendName);
        legendDTO = dto;
        LegendDAO dao = new LegendDAO();
        Logger.getLogger(LegendController.class.getName()).warning("Edit dto set");
        try {
            List<Legend> legends = dao.getDetailForEditLegend(dto.getLegendName());
            if (legends == null || legends.isEmpty()) {
                dto.getList().add(new Legend());
            } else {
                dto.setList(legends);
            }
        } catch (SQLException ex) {
            Logger.getLogger(LegendController.class.getName()).warning("SQL EXception has occoured");
        }
        Logger.getLogger(LegendController.class.getName()).warning("In Edit Legend Function The size of list" + dto.getList().size());

    }
}

//xhtml代码

       <?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:rich="http://richfaces.org/rich"
      xmlns:a4j="http://richfaces.org/a4j"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:ui="http://java.sun.com/jsf/facelets">
    <h:head>
        <title>Facelet Title</title>
    </h:head>
    <h:body>
        <ui:composition template="/legendTemplate.xhtml">
            <ui:define name="windowTitle">Change Legend</ui:define>
            <ui:define name="content">


                <h:messages globalOnly="true"/>
                <rich:panel id="firstPanel">
                    <h:form id="nis_viewLegend">
                        <rich:dataTable id="data_tbl" value="#{legendbean.legendDTOs}" var="legendDTOvar" style="width:100%" rendered="#{!legendbean.edit and not empty legendbean.legendDTOs}">
                            <rich:column>
                                <f:facet name="header">
                                    <h:outputText value="Description"/>
                                </f:facet>
                                <h:outputText value="#{legendDTOvar.desc}"/>
                            </rich:column>

                            <rich:column>
                                <f:facet name="header">
                                    <h:outputText value="Legend Type"/>
                                </f:facet>
                                <h:outputText value="#{legendDTOvar.legendName}"/>
                            </rich:column>

                            <rich:column>
                                <f:facet name="header">
                                    <h:outputText value="Legend Type"/>
                                </f:facet>
                                <h:outputText value="#{legendDTOvar.legendFor}"/>
                            </rich:column>

                            <rich:column>

                                <a4j:commandLink value="Delete" actionListener="#{legendbean.deleteLegendType(legendDTOvar)}" render=":firstPanel"/>
                                <h:outputText value="/"/>
                                <a4j:commandLink value="Edit" actionListener="#{legendbean.editLegendType(legendDTOvar)}" render=":secondPanel :editLegendForm :nis_viewLegend"/>

                            </rich:column>

                        </rich:dataTable>
                    </h:form>
                </rich:panel>

                <rich:panel id="secondPanel">
                    <h:form id="editLegendForm" rendered="#{legendbean.edit}">
                        <h:outputText value="Legend Name"/><br/>
                        <h:inputText value="#{legendbean.legendDTO.legendName}"  readonly="true"/><br/>

                        <h:outputText value="Description"/><br/>
                        <h:inputText value="#{legendbean.legendDTO.desc}"/><br/>

                        <h:outputText value="Legend For"/><br/>
                        <h:inputText value="#{legendbean.legendDTO.legendFor}"/><br/>
                        <br/> 
                        <h:outputText value="Range"  />  
                        <rich:dataTable id="editDataPnl" value="#{legendbean.legendDTO.list}" var="legend" style="width:100%">

                            <rich:column>
                                <f:facet name="header">
                                    <h:outputText value="SN"/>
                                </f:facet>
                                <h:inputText value="#{legend.sn}"/>
                            </rich:column>

                            <rich:column>
                                <f:facet name="header">
                                    <h:outputText value="Description"/>
                                </f:facet>
                                <h:inputText value="#{legend.desc}"/>
                            </rich:column>

                            <rich:column>
                                <f:facet name="header">
                                    <h:outputText value="Lower Range"/>
                                </f:facet>
                                <h:inputText value="#{legend.lowerRange}"/>
                            </rich:column>

                            <rich:column>
                                <f:facet name="header">
                                    <h:outputText value="Upper Range"/>
                                </f:facet>
                                <h:inputText value="#{legend.upperRange}"/>
                            </rich:column>

                            <rich:column>
                                <f:facet name="header">
                                    <h:outputText value="Color"/>
                                </f:facet>
                                <h:inputText value="#{legend.color}"/>
                            </rich:column>

                            <rich:column>
                                <a4j:commandLink value="Add" actionListener="#{legendbean.addLegendRange}" render=":secondPanel"/>
                                <h:outputText value=" / "/>
                                <a4j:commandLink value="Remove" actionListener="#{legendbean.removeLegendRange(legend)}" render=":secondPanel"/>
                            </rich:column>
                        </rich:dataTable>

                        <br/>
                        <center>
                            <a4j:commandButton value="SAVE" action="#{legendbean.saveLegend()}" render=":firstPanel :secondPanel"/>
                            <a4j:commandButton value="CANCEL" action="#{legendbean.cancel()}" render=":firstPanel :secondPanel"/>
                        </center>
                    </h:form>
                </rich:panel>

            </ui:define>

        </ui:composition>
    </h:body>
</html>
4

3 回答 3

1

例如,在 ViewScope 中,一旦构建了视图,form.xhtml只要您不离开该视图,它的数据就会持续存在。为了保持在同一个视图中,您应该调用具有返回类型void(通常在actionListener属性中使用)或返回 null 的方法,以防返回导航结果。

  • 方法表达式

在您的情况下,您的方法是无效的,但不是将它传递给动作侦听器,而是在视图中调用它。

尝试像这样更改类似的代码:

<a4j:commandButton value="SAVE" actionListener="#{legendbean.saveLegend()}" render="mainPnl"/>

对此:

<a4j:commandButton value="SAVE" actionListener="#{legendbean.saveLegend}" render="mainPnl"/>

由于actionListener属性已经需要一个方法表达式。

  • 数据表内的表格

我还注意到您的数据表中有一个表单。这可能会导致奇怪的行为,因为您的表单id将在结果页面中重复。为此,您应该尝试将表单放在数据表之外。

更好的是,您可以只有一个表单包含整个代码,因为嵌套表单是无效的 HTML 代码。

我建议你也检查一下你的legendTemplate.xhtml嵌套表格。

  • 豆类建设

为了初始化您的 bean 状态,建议使用@PostContruct方法而不是 bean 构造函数。

尝试从这里改变:

        public LegendController() {
            legendDTO = new LegendDTO();
            legendDTO.getList().add(new Legend());
        }

对此:

        @PostConstruct
        public void reset() {
            legendDTO = new LegendDTO();
            legendDTO.getList().add(new Legend());
        }

并删除您的构造函数。

只要您在同一个视图(又名 .xhtml 页面)中,就应该保留您的 bean 数据。

我希望它有所帮助。

于 2012-10-09T10:32:00.417 回答
1

我有同样的问题。我认为上面的答案并不能真正解决这个问题。由于提交任何表单,他没有遇到问题 - 按下这些按钮本身会导致整个页面重新呈现,这意味着在按下按钮之前对视图状态的引用已经消失。这也是我正在观察的。对我来说,只有当有很多大型搜索结果时才会发生这种情况,并且只需重新提交我刚刚所做的相同搜索即可重新呈现页面(不执行搜索)。我认为问题与可以通过表单传递给服务器的数据量的限制有关:在视图范围内,所有数据都被序列化并以一个长隐藏值作为表单中的值传递. 如果该值太长,服务器将不接受它,因此,

我知道这不是确定的,但这只是我能找到的关于这个问题的线索,所以我希望它有助于为其他人阐明或激发更好的信息。如果您有更确定的内容,请告诉我们。

编辑:我现在确信这是问题所在。我的模型 bean 引用了一个文件 blob。一旦我用布尔值替换了那个引用(只需要知道它是否存在),问题就消失了。尝试传递对 DTO/DAO 的引用而不是对象本身,或者将它们标记为不需要它们持久存在的“瞬态”。或者,如果可能的话,像我一样减轻物体的重量。

于 2013-04-15T18:35:06.040 回答
0

您是否尝试为函数 saveLegend() 和 cancel() 返回 null 而不是返回空字符串?

public String saveLegend() {
     ---------
     return null;
}

public String cancel() {
     ----------
     return null;
}

ajax 请求的返回也可能无效。但是,如果我没记错的话,返回 null 的 Richfaces 是唯一的解决方案。试试看。:) cancel() 在重新初始化 bean 时起作用。

正如 Bento 所回答的,您不能使用 actionListener 传递值。改用行动。

延伸阅读:

于 2012-10-19T19:16:45.110 回答