我创建了一个复合组件,它扩展了命令按钮并添加了一些ajax函数(onBegin,onComplete和onSuccess),但是我遇到了一些我无法解决的问题:
当我点击按钮并发生验证错误时,成功事件函数传递#{facesContext.validationFailed} = false而不是true,即使表单再次渲染; (html在调用成功事件之前呈现,对吗?)
logstash-*
Javascript文件
<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>
使用组件:
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;
}
}
}
答案 0 :(得分:1)
在生成HTML输出时评估EL表达式。它们在JavaScript事件期间不会被评估。右键单击并查看源。你看,它是一个和所有的HTML / JS。没有JSF组件,没有EL表达式。 JSF“只是”一个HTML代码生成器。
因此,当您加载页面时,#{facesContext.validationFailed}
将打印false
。 正是这个值作为JS函数参数传递。只有在将JSF组件作为JS函数参数传递之前重新呈现负责打印#{facesContext.validationFailed}
的JSF组件时,它才会起作用。
标准JSF没有提供将附加信息传递给ajax响应的工具。 PrimeFaces和OmniFaces等组件库通过自定义PartialViewContext
支持此功能。 PrimeFaces在validationFailed
对象中甚至还有一个内置args
属性,该属性可用于任何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>