【问题标题】:Whole form submited even with Ajax Listener使用 Ajax 侦听器的整个表单提交事件
【发布时间】:2020-04-21 17:43:30
【问题描述】:

我是 JSF 开发的新手。我将 Eclipse 与 JDK 1.8.0_172、WildFly 16、JSF 2.3、PrimeFaces 7.0 数据表一起使用。我开发了一个名为 FrmTest.xhtml 的页面,其中包含一个具有视图范围的托管 bean。加载页面后,当用户单击 NEW 按钮时,我想在数据表中添加一个新行。但是整个表单都提交了。我知道 ajax 在不提交整个表单的情况下进行处理。我应该更改什么以便不提交整个表单但将行添加到数据表中?

xhtml如下:

<!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:ui="http://java.sun.com/jsf/facelets"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:p="http://primefaces.org/ui">

    <h:head>    
    </h:head>
    <h:body>


        <div class="ToolBar" style="background-color:cadetblue;padding:10px;" > 
            <h:commandButton id="btnNewP"   value="new" global="false">
                <f:ajax event="click" execute="btnNewP" listener="#{testing.ButtonNew}" render="dataList"  />
            </h:commandButton>  
        </div>  

        <h:form id="FrmTest">  

            <p:dataTable id="dataList" value="#{testing.getListDto()}"  var="lst" Form="FrmTest" paginator="true" rows="20" paginatorPosition="top"  editable="true" editMode="cell"  rowKey="#{lst.vsCode}" rowIndexVar="rowNumber" selectionMode="single">
                    <f:facet name="header">
                        List of Vat Status
                    </f:facet>

                    <p:column  headerText="Selected">
                        <div style="text-align: center;">
                            <p:selectBooleanCheckbox value="#{lst.isSelected}"  />
                        </div>
                    </p:column>

                    <p:column id="Code" headerText="Code">
                        <p:cellEditor>
                            <f:facet name="output">
                                <h:outputText value="#{lst.vsCode}" />
                            </f:facet>
                            <f:facet name="input">
                                <p:inputText value="#{lst.vsCode}" >
                                <p:ajax event = "blur" listener="#{testing.onCellBlur(rowNumber, 'Code')}" update="dataList"  />
                                </p:inputText>
                            </f:facet>
                        </p:cellEditor>
                    </p:column>                 

                    <p:column id="Name" headerText="Name">
                         <p:cellEditor>
                            <f:facet name="output">
                                <h:outputText value="#{lst.vsName}" />
                            </f:facet>
                            <f:facet name="input">
                                <p:inputText value="#{lst.vsName}" >
                                <p:ajax event = "blur" listener="#{testing.onCellBlur(rowNumber, 'Name')}" update="dataList"  /> 
                                </p:inputText>
                            </f:facet>
                         </p:cellEditor>
                    </p:column>

                    <p:column id="Description" headerText="Description">
                         <p:cellEditor>
                            <f:facet name="output">
                                <h:outputText value="#{lst.vsDescription}"  />
                            </f:facet>
                            <f:facet name="input">
                                <p:inputText value="#{lst.vsDescription}" >
                                <p:ajax event = "blur" listener="#{testing.onCellBlur(rowNumber, 'Description')}" update="dataList"  /> 
                                </p:inputText>
                            </f:facet>
                         </p:cellEditor>
                    </p:column>

                    <p:column  headerText="is Active">
                        <div style="text-align: center;">
                            <p:selectBooleanCheckbox value="#{lst.isActive}"  />
                        </div>
                    </p:column>                     

                    <p:column headerText="Modified By" style="display:none;">
                        <h:outputText id="ModifiedBy" value="#{lst.modifiedBy}" />
                    </p:column>

                    <p:column headerText="Modified Date" style="display:none;">
                        <h:outputText id="ModifiedDate" value="#{lst.modifiedDate}" />
                    </p:column>     

                    <p:column headerText="Row State" style="display:none;">
                        <h:outputText id="RowState" value="#{lst.rowState}" />
                    </p:column>     

                    <p:column headerText="Error Description" style="display:none;">
                        <h:outputText id="ErrorDescription" value="#{lst.errorDescription}" />
                    </p:column>     

            </p:dataTable>

          </h:form> 

    </h:body>

</html>

NEW按钮的编码如下

public void ButtonNew() {

try {
    System.out.println("ButtonNew, Entry");

    Date modifiedDate = new Date(); 
    dtoUpdated = new VatStatusDto(false, " ", " ", " ", 0.00, " ", " ", " ", " ", " ", "Y", true,  getSessionUserCode(), modifiedDate, modifiedDate.toString(),  " ", " ", "Added");    

    listDto.add(0, dtoUpdated);
    PrimeFaces.current().ajax().update("FrmTest:dataList");

}
catch (Exception e) {
    System.out.println("FrmTest, ButtonNew: " + e.getMessage() + ", " + e.getCause() + ", " + e.getStackTrace());       
}

}

【问题讨论】:

    标签: ajax jsf primefaces


    【解决方案1】:

    我知道 ajax 会在不提交整个表单的情况下进行处理。

    不,那你理解错了(至少在基本 ajax 和 PrimeFaces/JSF 的上下文中)。这不是 ajax 所做的... Ajax 基本上“只”进行部分页面更新,在 response 中只更新那些被告知要更新的页面部分。 “ajax”中没有任何内容表明它应该优化其他事情,例如(默认情况下)对服务器端的表单元素进行部分处理/执行或强制客户端将表单(输入)从客户端部分提交到服务器。

    PrimeFaces update/process or plain JSF render/execute 属性的行为有一个很好的部分来优化哪些部分实际上是从客户端提交的。您可以按输入、表单或全局(完整应用程序)有效地执行此操作,因此我不会在此处复制该部分。

    另见:

    【讨论】:

    • 感谢您的回答。我尝试了部分更新,但问题仍然存在。我不希望在添加新行时提交整个页面。如何实现?
    • 开始阅读链接仔细...(部分)更新!=部分提交...
    【解决方案2】:

    @Kukeltje,非常感谢您的意见。我读了你寄来的东西。我删除了所有 PrimeFaces 对象,所有 ajax 调用。问题依然存在。问题是由于我犯了一个愚蠢的错误。我的托管 bean,视图范围,扩展了另一个标记为请求范围的类。我将其更改为查看范围,当我单击命令按钮时,不再发生整个表单提交。

    【讨论】:

    • 我猜您对“提交的整个表单”的定义与我们的预期不同。相反,您可能想用技术术语来描述“提交的整个表单”对您意味着什么。我们当然明白,这意味着 HTTP 负载包含 所有 表单元素,而不仅仅是 PrimeFaces Ajax 组件的process 属性中定义的元素。这与 bean 范围无关。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-08-20
    • 1970-01-01
    • 1970-01-01
    • 2014-08-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多