【问题标题】:Execute two AJAX calls in commandButton onclick bootsfaces jsf在 commandButton onclick bootsfaces jsf 中执行两个 AJAX 调用
【发布时间】:2018-04-04 19:03:37
【问题描述】:

我有一个带有表单的模态,我想要的是首先从 bean 关闭模态(方法“cerrarModal”),然后执行在数据库中插入的 AJAX(方法“crearUsuario”)。我看到了this question,但它对我不起作用。
这是我的按钮:

<b:commandButton value="Guardar" ajax="true" 
                 update="formTblUsuarios:growlMsg formTblUsuarios:tblUsuarios rowModal" 
                 id="btnGuardarUsuario" look="primary" 
                 onclick="ajax:admUsuariosBean.cerrarModal();admUsuariosBean.crearUsuario()" />


这些是我的 bean 方法:

public void cerrarModal() {
    RequestContext.getCurrentInstance().execute("$('#usuarioModal').modal('hide');");
}

public void crearUsuario() {
    try {
        if (this.fachada.crearUsuario(getUsr())) {
            this.reestablecerClave();FacesMessages.info("User created.");
        } else {
            FacesMessages.warning("The user was not created.");
        }
    } catch (Exception e) {
        FacesMessages.error("The user was not created.");
}

但是服务器抛出这个错误:

2018 年 4 月 4 日上午 11:02:14 com.sun.faces.lifecycle.InvokeApplicationPhase 执行 广告:无法解析表达式 [#{admUsuariosBean.cerrarModal();admUsuariosBean.crearUsuario()}] javax.el.E​​LException:无法解析表达式 [#{admUsuariosBean.cerrarModal();admUsuariosBean.crearUsuario()}] 在 org.apache.el.lang.ExpressionBuilder.createNodeInternal(ExpressionBuilder.java:145) 在 org.apache.el.lang.ExpressionBuilder.build(ExpressionBuilder.java:171) 在 org.apache.el.lang.ExpressionBuilder.createValueExpression(ExpressionBuilder.java:216) 在 org.apache.el.E​​xpressionFactoryImpl.createValueExpression(ExpressionFactoryImpl.java:66) 在 net.bootsfaces.component.ajax.AJAXBroadcastComponent.evalAsValueExpression(AJAXBroadcastComponent.java:74) 在 net.bootsfaces.component.ajax.AJAXBroadcastComponent.executeAjaxCalls(AJAXBroadcastComponent.java:123) 在 net.bootsfaces.component.ajax.AJAXBroadcastComponent.broadcast(AJAXBroadcastComponent.java:52) 在 javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:790) 在 javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1282) 在 com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:81) 在 com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101) 在 com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:198) 在 javax.faces.webapp.FacesServlet.service(FacesServlet.java:646) 在 org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303) 在 org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) 在 org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) 在 org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) 在 org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) 在 com.abcpagos.otis.beans.Filtro.doFilter(Filtro.java:44) 在 org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) 在 org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) 在 org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220) 在 org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122) 在 org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:503) 在 org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170) 在 org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103) 在 org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950) 在 org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116) 在 org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:421) 在 org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1070) 在 org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:611) 在 org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:316) 在 java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) 在 java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) 在 org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) 在 java.lang.Thread.run(Thread.java:748) 引起:org.apache.el.parser.ParseException:遇到“”; “”在第 1 行第 32 列。 期待其中之一: "}" ... “。” ... “[”... ">" ... “gt”... “=” ... “格”…… "


我正在使用 BootsFaces 1.2.0、PrimeFaces 6.1、JSF 2.2、(XAMPP) Apache Tomcat 7.0.56。
谢谢。

【问题讨论】:

    标签: ajax jsf bootsfaces


    【解决方案1】:

    首先,@Holger 的答案(大部分)是正确的:您的特定用例不需要 AJAX 调用。但是,有些用例需要两个连续的 AJAX 调用,所以我还是会问你原来的问题。

    我以一种非常简单的方式实现了 BootsFaces 的解析器。 onclick 处理程序可能由三部分组成:在 AJAX 调用、AJAX 调用之前执行的 JavaScript 部分,以及在将 AJAX 请求发送到服务器之后执行的第二个 JavaScript 部分。请注意,第二个 JavaScript 位几乎肯定在 Java 代码之前执行。

    理论上,我可以在实现 AJAX 引擎时考虑多个 AJAX 调用。但是,我没有看到这样做的意义:调用一个 Java 方法调用两个方法比触发两个 AJAX 调用更容易,每个调用一个 Java 方法并每个更新 DOM。

    但是……永远不要说永远。如果你真的需要两个连续的 AJAX 调用,你可以使用&lt;b:remoteCommand&gt; 来实现。这样的&lt;b:remoteCommand&gt; 是一个JavaScript 函数,通过AJAX 调用Java 方法并更新DOM。所以你可以在onComplete处理程序中调用&lt;b:remoteCommand&gt;来触发第二个AJAX请求。

    就是这样。但是,您只是想关闭模式,因此我建议您像这样实现它:

    <b:commandButton value="Guardar"
             update="..." 
             onclick="$('#usuarioModal').modal('hide');ajax:admUsuariosBean.crearUsuario()" />
    

    【讨论】:

    • 谢谢,但我想提供一些上下文:我验证了模态框内的表单,如果我在 onclick 事件中关闭模态框,则不会显示验证,因为模态框已关闭。我意识到如果表单验证失败,则不会执行 ajax 调用,并且我的模态可以保持打开状态,直到验证成功。这就是我创建一个关闭模式的 bean 方法的原因,理论上它只有在验证成功时才会执行。我不能在 oncomplete 事件中使用 ajax 调用,以便使用该事件来关闭模式,然后在使用 oncomplete 之后,保存表单。
    • 查看showcase.bootsfaces.net/forms/FetchBeanInfos.jsf#basic_usage,了解如何通过单个 AJAX 调用解决任务。这个想法是添加一个&lt;b:fetchBeanInfo&gt;标签和一个oncomplete="if(!validationFailed) $('#usuarioModal').modal('hide')"。也就是说,这只是对您的解决方案的优化。底线是你的方法有效!
    • 谢谢,我仍然知道框架。 FetchBeanInfos 似乎对 Ajax 非常有用,我正在尝试使用它实现更好的解决方案。
    【解决方案2】:

    您不需要 bean 来关闭模态表单。

    <b:commandButton value="Guardar" ajax="true" 
                 update="formTblUsuarios:growlMsg formTblUsuarios:tblUsuarios rowModal" 
                 id="btnGuardarUsuario" look="primary" 
                 actionListener="#{admUsuariosBean.crearUsuario()}"
                 oncomplete="$('#usuarioModal').modal('hide')"
     />
    

    【讨论】:

    • 谢谢伙计,但我需要的是先关闭模式,然后再执行 bean 方法。 ajax调用完成时执行oncomplete事件,意思是直到bean方法完成,modal一直是打开的,我需要的是others。
    • 当且仅当一切正常时,大多数人都希望关闭模式。所以在大多数情况下,Holger 的答案是要走的路(可能由&lt;b:fetchBeanInfo&gt; 保护)。如果您不关心验证约束等问题,请查看我的答案。
    • 您可以通过onclick替换oncomplete,在ajax调用之前模态框将被关闭。
    • 另见showcase.bootsfaces.net/forms/FetchBeanInfos.jsf#basic_usage。这个特定的演示以相反的方式进行:当且仅当验证约束得到满足时,它才会打开模式。但是,只要存在违反验证规则的情况,您就可以使用相同的想法来防止模式关闭。这就是 oncomplete 的用例:在处理 JSF 请求后调用它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-05-02
    • 1970-01-01
    • 2017-02-21
    • 2019-01-29
    • 2016-09-28
    • 2014-12-01
    • 2014-06-11
    相关资源
    最近更新 更多