JSF / Primefaces动作侦听器未从p:commandButton调用

时间:2013-06-30 18:27:43

标签: ajax jsf primefaces

我正在将JSP / Servlets网站迁移到JSF,并且难以实现JSF的一些更有趣的功能。我试图解决了几天的当前问题是从<p:dataTable>删除一行或多行。以下代码段定义了表:

<ui:composition template="/templates/RescueDBAdminTemplate.xhtml" ... > 
<ui:define name="body">
    <div id="mainContent">
        <h1> Pet Information Edit </h1>

        <p>
           This page allows the detailed information for an animal to be inserted or edited.
        </p>
        <br />

        <!--
        ~~~~ The first row contains the AIF number, and two optional hyperlinks to the History and Cage Card
        ~~~~ pages.  Since we have at most three entries, and a layout of 4 columns, we will need a sub-table
        ~~~~ to evenly space out these objects.
        ~~~~ -->
        <table class="w100pct">
           <tr>
              <!--
              ~~~~ Display the AIF_NO for the animal at the top of the page.  For Reference Only.
              ~~~~ -->
              <td class="label" align="left" >
                 AIF Number: #{animals.aifNo}
              </td>

              <td align="center"> <a href="/${context}/Protected/AifServlet?COMMAND=HISTORY&amp;AIF_NO=${aifBean.aifNo}" target="window"> Display History   </a> </td>
              <td align="right">  <a href="/${context}/Protected/AifServlet?COMMAND=CARD&amp;AIF_NO=${aifBean.aifNo}"    target="window"> Display Cage Card </a> </td>
           </tr>
        </table>

        <p:accordionPanel id="profile" multiple="true" activeIndex="0,1,2,3,4,5,6,7">
            <p:tab title="Cage Card Information">
                <h:form id="cageCardForm">
                    <p:panelGrid styleClass="rdbGrid w100pct">
                        <p:row>
                            <p:column styleClass="block"> Child Friendly: </p:column>
                            <p:column>
                                <p:selectOneMenu id="childFriendly" value="#{animals.isChildFriendly}">
                                    <f:selectItem itemValue="Y" itemLabel="Yes"     />
                                    <f:selectItem itemValue="N" itemLabel="No"      />
                                    <f:selectItem itemValue="U" itemLabel="Unknown" />
                                    <f:selectItem itemValue="O" itemLabel="Older Children Only" />
                                </p:selectOneMenu>
                            </p:column>
                            <p:column styleClass="block"> Dog Friendly:   </p:column>
                            <p:column>
                                <p:selectOneMenu id="dogFriendly" value="#{animals.isDogFriendly}">
                                    <f:selectItem itemValue="Y" itemLabel="Yes"       />
                                    <f:selectItem itemValue="N" itemLabel="No"        />
                                    <f:selectItem itemValue="U" itemLabel="Unknown"   />
                                    <f:selectItem itemValue="T" itemLabel="Tolerates" />
                                    <f:selectItem itemValue="S" itemLabel="Some"      />
                                </p:selectOneMenu>
                            </p:column>
                        </p:row>
                        <p:row>
                            <p:column styleClass="block"> Cat Friendly:   </p:column>
                            <p:column>
                                <p:selectOneMenu id="catFriendly" value="#{animals.isCatFriendly}">
                                    <f:selectItem itemValue="Y" itemLabel="Yes"       />
                                    <f:selectItem itemValue="N" itemLabel="No"        />
                                    <f:selectItem itemValue="U" itemLabel="Unknown"   />
                                    <f:selectItem itemValue="T" itemLabel="Tolerates" />
                                    <f:selectItem itemValue="S" itemLabel="Some"      />
                                </p:selectOneMenu>
                            </p:column>
                            <p:column styleClass="block"> Housebroken:    </p:column>
                            <p:column>
                                <p:selectOneMenu id="housebroken" value="#{animals.isHousebroken}">
                                    <f:selectItem itemValue="Y" itemLabel="Yes"       />
                                    <f:selectItem itemValue="N" itemLabel="No"        />
                                    <f:selectItem itemValue="U" itemLabel="Unknown"   />
                                </p:selectOneMenu>
                            </p:column>
                        </p:row>

                        <p:row>
                            <p:column styleClass="block" style="text-align:top;"> Cage Card Comments:  </p:column>
                            <p:column> <p:inputTextarea name="previousOwner" rows="11" cols="40" value="#{animals.cageCardComment}" /> </p:column>
                            <p:column styleClass="block" style="text-align:top;"> Lifestyle Needs:  </p:column>
                            <p:column> <p:inputTextarea name="reasonObtained" rows="11" cols="40" value="#{animals.lifestyleNeeds}" /> </p:column>
                        </p:row>
                    </p:panelGrid>
                </h:form>
            </p:tab>
            <p:tab title="Fees and Expenditures">
                <h:form id="feesForm">
                    <p:panelGrid styleClass="rdbGrid w100pct">
                       <p:row>
                           <p:column styleClass="block"> Adoption Fee:  </p:column>
                        <p:column>
                            <p:inputText size="16" value="#{animals.adoptionFee}" maxlength="64" />
                        </p:column>
                        <p:column styleClass="block"> Normal Costs:  </p:column>
                        <p:column>
                            <p:inputText size="16" value="#{animals.costRegular}" maxlength="64" />
                        </p:column>
                    </p:row>
                    <p:row>
                        <p:column styleClass="block"> Extra Costs:   </p:column>
                        <p:column>
                            <p:inputText size="16" value="${aifBean.costNonRegular}" maxlength="64" />
                        </p:column>
                        <p:column styleClass="block"> Extra Cost Description </p:column>
                        <p:column>
                            <p:inputTextarea rows="4" cols="40" value="#{animals.nonRegularDesc}" />
                        </p:column>
                    </p:row>
                    <p:row>
                        <p:column styleClass="block"> Comments </p:column>
                           <p:column colspan="3">
                                <p:inputTextarea rows="2" cols="80" value="#{animals.comments}" />
                        </p:column>
                    </p:row>
                    </p:panelGrid>
                </h:form>
            </p:tab>
            <p:tab title="Medical History">
                <p:dataTable styleClass="w100pct" var="current" value="#{medical.getMedHistoryByAifNo(param.AIF_NO)}">
                    <p:column headerText="Delete">
                        Delete
                    </p:column>

                    <p:column headerText="Procedure Name">
                        #{current.shortName}
                    </p:column>

                    <p:column headerText="Date">
                        #{current.treatmentDate}
                    </p:column>

                    <p:column headerText="Vet Information">
                        #{current.vetName} #{current.vetClinic}
                    </p:column>

                    <p:column headerText="Comments">
                        #{current.comments}
                    </p:column>
                </p:dataTable>
            </p:tab>   
            <p:tab title="Documents">
                <h:form id="docListForm">
                    <p:dataTable id="docListTable" styleClass="w100pct" var="current" value="#{documents.currentDocList}"
                                 paginator="true" rows="10" selection="#{documents.selectedDocs}">

                        <p:column selectionMode="multiple" style="width:2%" />  

                        <p:column headerText="Date">
                            <h:outputText value="#{current.treatmentDate}" />
                        </p:column>

                        <p:column headerText="Document Type">
                            <h:outputText value="#{current.group}" converter="com.rescuedb.DocGroupName" />
                        </p:column>

                        <p:column headerText="Description">
                            #{current.description}
                        </p:column>

                        <f:facet name="footer">  
                            <p:commandButton id="docListDelete" value="Delete Selected Records" 
                                             icon="ui-icon-search" 
                                             update=":#{p:component('docListTable')}" 
                                             actionListener="#{documents.deleteReference}" >
                                <f:param name="docNo" value="#{current.docNo}" />
                                <f:param name="refNo" value="#{animals.aifNo}" />
                                <f:param name="group" value="#{current.group}" />
                            </p:commandButton>  
                        </f:facet>
                    </p:dataTable>
                </h:form>
            </p:tab>
        </p:accordionPanel>

    </div>
</ui:define>
</ui:composition>

支持此页面的托管bean如下所示(这是相当初步的代码,因为我还在尝试使用PrimeFaces和JSF):

package com.rescuedb.beans.managed;

import java.io.Serializable;
import java.util.List;
import java.util.Map;

import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;

import org.apache.log4j.Logger;

import com.rescuedb.Beans.DocMasterBean;
import com.rescuedb.Beans.DAO.DocMaster;
import com.rescuedb.Beans.DAO.DocXref;
import com.rescuedb.Beans.Models.DocMasterDataModel;
import com.rescuedb.Core.RescueException;

@ManagedBean(name="documents")
@ViewScoped
public class DocumentManagedBean implements Serializable
{

    static final long serialVersionUID = 5L;

    static Logger logger = Logger.getLogger(DocumentManagedBean.class);

    private transient DocMaster             docInfo;            // Document Master accessor object
    private transient DocXref               xrfInfo;            // Document Master accessor object

    private String  currentAifNo;
    private String  refNo;
    private String  docNo;

    /**
     * Contains a list of document records, wrapped in a DataModel, for the currently 
     * active foster animal.
     */
    private DocMasterDataModel currentDocList = null;           

    private DocMasterBean[] selectedDocs;

    public DocumentManagedBean()
    {
        logger.trace ("DocumentManagedBean.constructor");
        try {
            //
            // Retrieve the URL parameter from the context.
            //
            FacesContext       context    = FacesContext.getCurrentInstance();
            Map<String,String> paramMap   = context.getExternalContext().getRequestParameterMap();
            String             paramAifNo = paramMap.get("AIF_NO");

            if (paramAifNo != null) {
                if (!paramAifNo.isEmpty()) {
                    currentAifNo = paramAifNo;
                    loadCurrentDocList();
                }
            }
        } catch (Exception e) {
            logger.error ("Exception caught in DocumentManagedBean() constructor :: " + e.getMessage(), e);
        }
    }

    /**
     * Initialize the bean from the database.   
     */
    @PostConstruct
    public void initialize ()
    {
        logger.trace ("DocumentManagedBean.initialize");
        try {
            docInfo = new DocMaster();
            xrfInfo = new DocXref();
        } catch (Exception e) {
            logger.error ("Exception in DocumentsManagedBean.initialize() : " + e.getMessage(), e);
        }
    }

    public List<DocMasterBean> getDocList()
    {
        logger.trace ("DocumentManagedBean.getDocList");
        return docInfo.getRecordList();
    }

    /**
     * Retrieve the list of documents that are associated wit a specific foster animal.
     * <p>
     * @param aifNo
     * @return
     */
    public DocMasterDataModel getCurrentDocList()
    {
        logger.trace ("DocumentManagedBean.getCurrentDocList");
        return currentDocList;
    }

    /**
     * Load the document list for the currently active foster animal.
     */
    private void loadCurrentDocList()
    {
        DocMaster docMaster = null;

        logger.info ("DocumentManagedBean.loadCurrentDocList");
        try {
            docMaster = new DocMaster();
            if (currentAifNo != null) {
                if (!currentAifNo.isEmpty()) {
                    docMaster.queryByRefNo (Integer.parseInt(currentAifNo));
                    currentDocList = new DocMasterDataModel (docMaster.getRecordList());
                    logger.info ("DocumentManagedBean.loadCurrentDocList :: currentDocList reloaded, length = " + docMaster.getRecordCount());
                } else {
                    logger.info ("DocumentManagedBean.loadCurrentDocList :: currentAifNo is empty, no records loaded.");
                }
            } else {
                logger.info ("DocumentManagedBean.loadCurrentDocList :: currentAifNo is null, no records loaded.");
            }
        } catch (Exception e) {
            logger.error ("Exception in DocumentsManagedBean.loadCurrentDocList() : " + e.getMessage(), e);
        }
    }

    public void deleteReference(ActionEvent event)
    {
        boolean        status;                // Status of the update.
        int            refNo = 0;
        int            docNo = 0;

        logger.info ("DocumentManagedBean.deleteReference");
        try {
            //
            // Retrieve the parameter of the request.
            //
            FacesContext       context    = FacesContext.getCurrentInstance();
            Map<String,String> paramMap   = context.getExternalContext().getRequestParameterMap();
            String             paramDocNo = paramMap.get("docNo");
            String             paramRefNo = paramMap.get("refNo");
            logger.info (String.format("DocumentManagedBean.deleteReference :: paramDocNo = [%s]", paramDocNo));
            logger.info (String.format("DocumentManagedBean.deleteReference :: paramRefNo = [%s]", paramRefNo));

            //
            // Retrieve the items necessary to delete the proper records.
            // The refNo parameter will only be specified when a specific cross-referenced
            // record is to be deleted.  If this value is missing, then the master document
            // is to be deleted.
            //
            if (paramRefNo != null) {
                try {
                    refNo = Integer.parseInt (paramRefNo);
                    this.refNo = paramRefNo;
                } catch (NumberFormatException e) {
                    refNo = 0;
                }
            }

            //
            // The docNo has to be present.  If the refNo is zero, then we will delete the
            // master document.  If a refNo is present, then we will delete a cross reference.
            //
            if (paramDocNo != null) {
                try {
                    docNo = Integer.parseInt (paramDocNo);
                    this.docNo = paramDocNo;
                } catch (NumberFormatException e) {
                    docNo = 0;
                    String message = String.format ("Illegal value for docNo (%d)", docNo);
                    logger.error(String.format("DocumentManagedBean.deleteReference :: Exception Message [%s]", message));
                    throw new RescueException ("DS000091", message, "DocumentsManagedBean", "deleteReference");
                }
            } else {
                logger.error("DocumentManagedBean.deleteReference :: paramDocNo is null");
            }

            //
            // Delete the cross reference record.
            //
            if (refNo != 0) {
                xrfInfo = new DocXref();
                status  = xrfInfo.queryByCrossRef (docNo, refNo);
                if (status != true) {
                    String message = String.format ("Error querying DOC_xref for refNo = %d, docNo = %d", refNo, docNo);
                    logger.error(String.format("DocumentManagedBean.deleteReference :: Exception Message [%s]", message));
                    throw new RescueException ("DS000092", message, "DocumentsManagedBean", "deleteReference");
                } else {
                    status = xrfInfo.delete();
                    logger.warn("DocumentManagedBean.deleteReference :: Document XRef deleted");
                    // logger.warn("DocumentManagedBean.deleteReference :: TEST TEST TEST Document XRef not actually deleted");
                    if (status != true) {
                        String message = String.format ("Error deleting DOC_xref for refNo = %d, docNo = %d", refNo, docNo);
                        logger.error(String.format("DocumentManagedBean.deleteReference :: Exception Message [%s]", message));
                        throw new RescueException ("DS000093", message, "DocumentsManagedBean", "deleteReference");
                    } else {
                        loadCurrentDocList();
                        logger.error("DocumentManagedBean.deleteReference :: currentDocList reloaded");
                    }
                }
            } else {
                logger.error("DocumentManagedBean.deleteReference :: refNo is 0.  No Records were deleted.");
            }
        } catch (RescueException e) {
            logger.error ("RescueException in DocumentsManagedBean.deleteReference() :: " + e.getMessage(), e);
        } catch (Exception e) {
            logger.error ("Exception in DocumentsManagedBean.deleteReference()", e);
        }
    }

    public DocMaster getDocInfo() 
    {
        logger.info ("DocumentManagedBean.getDocInfo");
        return docInfo;
    }

    public void setDocInfo(DocMaster docInfo) 
    {
        logger.info ("DocumentManagedBean.setDocInfo");
        this.docInfo = docInfo;
    }

    public String getRefNo() 
    {
        logger.info ("DocumentManagedBean.getRefNo");
        return refNo;
    }

    public void setRefNo(String refNo) 
    {
        logger.info ("DocumentManagedBean.setRefNo");
        this.refNo = refNo;
    }

    public String getDocNo()
    {
        logger.info ("DocumentManagedBean.getDocNo");
        return docNo;
    }

    public void setDocNo(String docNo) 
    {
        logger.info ("DocumentManagedBean.setDocNo");
        this.docNo = docNo;
    }

    public DocMasterBean[] getSelectedDocs() 
    {  
        logger.info ("DocumentManagedBean.getSelectedDocs");
        return selectedDocs;  
    }  

    public void setSelectedDocs(DocMasterBean[] selectedDocs) 
    {  
        logger.info ("DocumentManagedBean.setSelectedDocs");
        this.selectedDocs = selectedDocs;  
    }  
}

我尝试了很多不同的策略,并在其他StackOverflow线程中阅读了相当多的非常详细的解释(谢谢你,BalusC!),但是仍然无法实际调用动作监听器。 / p>

我的环境如下:

  • Java 1.6
  • Eclipse Kepler(最初是Juno)
  • GlassFish 3.1.2
  • PrimeFaces 3.5.0

从演示角度来看,XHTML正确显示。 <p:dataTable>元素的呈现方式与文档和示例一样,但是当我尝试删除一行时,永远不会调用该侦听器。

我尝试过多次更改更新名称。目前,update参数的值为profile:docListForm:docListTable

其他帖子似乎表明<p:commandButton>内的<p:accordianPanel>存在问题,但这是针对之前版本的PrimeFaces(3.2)。

我尝试将<p:commandButton>移到<p:dataTable>之外以及每行,但行为不会改变。

2 个答案:

答案 0 :(得分:2)

如果你的监听器没有触发尝试这个,它在p:tables

中工作正常
<p:column id="delete" headerText="Action"  width="65"> 
    <h:commandLink value="Delete" 
    action="#{documents.deleteReference(current.docNo,animals.aifNo,current.group)}"   ajax="false" />
</p:column>

在你的文件bean中:

public void deleteReference(String docNo, String aifNo, String group)

你实际上可以传递最终作为int转换的2个字符串,但是作为方法中的Integer包装器而不是原语。

干杯,

亨利

答案 1 :(得分:-1)

尝试在命令按钮中添加 ajax =“false”属性,类似这样。

<p:commandButton value="Non-Ajax Submit" actionListener="#{pprBean.savePerson}"   
        ajax="false" />  

或者也可以在 ajax =“false”使用 h:commandButton 。 在我的应用程序中,我有相同的问题充足的时间,我得到回答几周回到页面或代码在页面或托管bean抛出异常的问题或一些逻辑失败,这是生成JSF的异常,这是背后的主要原因触发事件。如果代码或逻辑在某处失败,则JSF2功能不会触发事件。可能这会对你有所帮助