在JSF Dialog AJAX CRUD上防止双重提交

时间:2012-11-08 02:19:33

标签: java ajax jsf-2 primefaces

我想知道为什么在我的应用程序中遇到这种行为。

我在UI中使用了primefaces,几乎所有的页面都遵循这种模式。我在所有的CRUD中都大量使用了AJAX 操作和使用对话框向用户显示它。

<ui:composition template="myTemplate.xhtml">
    <ui:define name="content">
        <ui:include
            src="/pages/CreateDialog.xhtml" />
        <ui:include
            src="/pages/UpdateDialog.xhtml" />
        <ui:include
            src="/pages/DeleteDialog.xhtml" />
    </ui:define>
</ui:composition>

我唯一担心的是,在我的对话框中做了CRUD之后,用户不小心点击了F5或刷新了浏览器, FF / Chrome和其他浏览器总是提到

To display this page, Firefox must send repeat action...

显然这会导致双重提交。以前我在旧版应用中使用了Post-Redirect-Get,但是从那以后 是AJAX JSF更新然后我不能这样做。

这是什么解决方法,这是正常的吗?我认为在浏览器刷新期间不应再触发AJAX操作。

帮助?

更新

我正在使用此代码打开对话框

<p:commandButton value="Add" 
        onclick="createWidget.show();"
        update=":CreateForm"
        action="#{MyBean.add}" 
        />

我的创建对话框使用此

<p:dialog  header="Create">
    <h:form id="CreateForm" prependId="false">
        <p:commandButton value="Add" icon="ui-icon-plus"
            actionListener="#{MyBean.add}"
            update=":messageGrowl" 
            oncomplete="closeDialogIfSucess(xhr, status, args, createWidget 'createDialogId')"/>
    </h:form>
</p:dialog>

我实际上正在关注此网站的页面... Full WebApplication JSF EJB JPA JAAS

1 个答案:

答案 0 :(得分:2)

在回调方法中遇到JavaScript错误的几次经历最终导致了这种行为。我能够重现你在纠正回调签名后消失的问题:

oncomplete="closeDialogIfSucess(xhr, status, args, createWidget, 'createDialogId')"

相应的JavaScript函数签名:

function closeDialogIfSucess(xhr, status, args, createWidget, dialogid)

(当然,如果您的JavaScript调用只有3个参数,则更正oncomplete调用)

无关:我猜您正在使用此功能关闭特定对话框。另一种方法是将widgetVar属性分配给对话框:

<p:dialog id="testDialog"  header="Create" widgetVar="createWidget">
    <h:form id="CreateForm" prependId="false">
        ...
    </h:form>
</p:dialog>

widgetVar对象将代表回调函数中的对话框,因此您可以通过调用对话框的hide()函数来关闭它:

function closeDialogIfSucess(xhr, status, args, createWidget) {
    if(args.validationFailed || !args.loggedIn) {  
        jQuery('#testDialog').effect("shake", { times:3 }, 100);  
    } else {  
        createWidget.hide();  
    }  
}