【问题标题】:Execute a script on f:ajax "success" event only when validation has not failed仅在验证未失败时对 f:ajax “成功”事件执行脚本
【发布时间】:2015-08-27 14:20:58
【问题描述】:

我已经创建了一个复合组件,它扩展了命令按钮并添加了一些 ajax 函数(onBegin、onComplete 和 onSuccess),但是我有一些我无法解决的问题:

当我单击按钮并发生验证错误时,即使再次呈现表单,也会传递成功事件函数 #{facesContext.validationFailed} = false 而不是 true; (html是在调用成功事件之前渲染的,对吧?)

<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:cc="http://java.sun.com/jsf/composite"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core">

<cc:interface shortDescription="CommandButton com Ajax">

    <cc:attribute name="onbegin"/>
    <cc:attribute name="oncomplete"/>
    <cc:attribute name="onsuccess"/>
    <cc:attribute name="render"/>
    <cc:attribute name="execute"/>
    <cc:attribute name="action" targets="commandButton"/>
    <cc:attribute name="actionListener" targets="commandButton"/>
    <cc:attribute name="value"/>
    <cc:attribute name="styleClass" targets="commandButton"/>
    <cc:attribute name="immediate" targets="commandButton"/>

</cc:interface>

<cc:implementation>

    <h:outputScript library="progutils" name="/js/commandButton.js" target="HEAD"/>

    <h:commandButton id="commandButton" value="#{cc.attrs.value}">
        <f:ajax render="#{cc.attrs.render}" execute="#{cc.attrs.execute}"
                onevent="function(data){execCommandButtonAjax(data, function(){ #{cc.attrs.onbegin} },function(){ #{cc.attrs.oncomplete} },function(){ #{cc.attrs.onsuccess} }, #{facesContext.validationFailed})}">
        </f:ajax>
    </h:commandButton>

</cc:implementation>

</html>

Javascript 文件

function execCommandButtonAjax(data, onBegin, onComplete, onSuccess, validationFailed) {
    var status = data.status;
    switch (status) {
        case 'begin': {
            onBegin();
            break;
        }
        case 'complete': {
            onComplete();
            break;
        }
        case 'success': {
            console.log('Validation Failed ' + validationFailed);
            if(!validationFailed){
                onSuccess();
            }
            break;
        }
    }
}

使用组件:

<pu2:commandButton id="btnPu2" 
                   onbegin="block(); console.log('begin')"                                                                    
                   oncomplete="unblock(); console.log('complete')"
                   onsuccess="console.log('success')"
                   execute="@form"
                   action="#{list.search()}"
                   render="@form :table-form :form-pagination"
                   value="Do it">
</pu2:commandButton>

【问题讨论】:

  • 每个问题1个问题。

标签: javascript ajax jsf-2 event-handling composite-component


【解决方案1】:

EL 表达式在生成 HTML 输出时进行评估。它们不会在 JavaScript 事件期间进行评估。右键单击并查看源代码。你看,它是一个和所有的 HTML/JS。没有 JSF 组件,没有 EL 表达式。 JSF “只是”一个 HTML 代码生成器。

因此,当您加载页面时,#{facesContext.validationFailed} 将打印 false正是这个值作为 JS 函数参数传递。只有在将负责打印 #{facesContext.validationFailed} 的 JSF 组件作为 JS 函数参数传递之前,它才会起作用。

标准 JSF 不提供将附加信息传递给 ajax 响应的工具。 PrimeFaces 和 OmniFaces 等组件库通过自定义 PartialViewContext 支持这一点。 PrimeFaces 在其 args 对象中甚至有一个内置的 validationFailed 属性,该属性可用于任何 oncomplete 属性。

最好的办法是有条件地渲染 onsuccess 脚本本身。

<h:commandButton id="commandButton" value="#{cc.attrs.value}">
    <f:ajax execute="#{cc.attrs.execute}" render="#{cc.attrs.render} onsuccess" 
            onevent="function(data){execCommandButtonAjax(data, function(){ #{cc.attrs.onbegin} },function(){ #{cc.attrs.oncomplete} })}">
    </f:ajax>
</h:commandButton>
<h:panelGroup id="onsuccess">
    <h:outputScript rendered="#{facesContext.postback and not facesContext.validationFailed}">
        #{cc.attrs.onsucces}
    </h:outputScript>
</h:panelGroup>

【讨论】:

  • 我明白了,#{facesContext.validationFailed} 打印为 true,因为按钮有一个 render="@form" (并且按钮在表单内),但是传递给 javascript 函数的值是 false ,可能是因为在调用函数时打印了值 false。
猜你喜欢
  • 2018-07-06
  • 1970-01-01
  • 1970-01-01
  • 2012-06-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-19
  • 2015-12-03
相关资源
最近更新 更多