在我的Managed Bean中,我有一个简单的布尔方法:
public class UploadBean {
// ...
public boolean getPossuiNotasFiscaisNaoTransmitidas() {
boolean result = false;
// Some computation ...
return result;
}
}
在我的XHTML页面中,我使用的是RichFaces 3.3.3 tabPanel。在特定标签中,我需要确认是否真的打开它:
<a4j:jsFunction name="possuiNotasFiscaisNaoTransmitidas" action="#{uploadBean.getPossuiNotasFiscaisNaoTransmitidas}" immediate="true" process="tab-10" ajaxSingle="true" reRender="tab-10"/>
<a4j:loadScript src="../../js/orcamentoVistoria.js"/>
<rich:tabPanel id="abas" switchType="ajax" >
<!-- many tabs... -->
<rich:tab
id="tab-10"
name="tab-10"
ontabenter="return prosseguirAbaNotasFiscais();"
ontableave="return prosseguirAbaNotasFiscais();" >
<!-- content -->
</rich:tab>
</rich:tabPanel>
prosseguirAbaNotasFiscais()
中的函数orcamentoVistoria.js
调用托管bean方法:
function prosseguirAbaNotasFiscais() {
console.info("prosseguirAbaNotasFiscais: Entrando"); // LOG 1
var serverResponse = possuiNotasFiscaisNaoTransmitidas();
console.info("prosseguirAbaNotasFiscais: serverResponse? " + serverResponse); // LOG 2
var result = serverResponse ? confirm("Proceed?"): true;
console.info("prosseguirAbaNotasFiscais: Resultado? " + result); // LOG 3
return result;
}
我的期望:当我在选项卡中输入(或离开)时,页面将调用托管bean方法。如果答案是真的,将询问用户是否要继续进入/离开。如果答案是错误的,那么选项卡将直接输入/离开。
我真正得到的:当我在选项卡中输入(或离开)时,页面显然调用托管bean方法。至少,在调试中,我可以看到正在执行的方法(实际上很多次)。但是,在JS返回(LOG 2
行)中,serverResponse
变量未定义。这就像页面没有等待服务器响应。因此,JS函数将始终返回true
,并且将始终直接输入/左侧选项卡。
那么,我该怎么办?它是<a4j:jsFunction>
代码中的某个特定属性吗?
由于
Rafael Afonso
更新2016年2月17日
@Makhiel,谢谢你的建议。但是,我需要的是,通过某种方式,在执行oncomplete
之后,允许或不允许更改选项卡。但是(至少我可以理解),只能通过标签中的ontabenter
或ontableave
来实现。
根据Makhiel的建议,我在我的代码中提出了以下建议:
Managed Bean
public class UploadBean {
private boolean questionarAbaNotasFiscais = false;
// ...
public boolean getPossuiNotasFiscaisNaoTransmitidas() {
this.questionarAbaNotasFiscais = false;
// Some computation. It can change questionarAbaNotasFiscais or not ...
return this.questionarAbaNotasFiscais;
}
// ...
public boolean isQuestionarAbaNotasFiscais() {
return questionarAbaNotasFiscais;
}
}
XHTML:
<a4j:jsFunction name="possuiNotasFiscaisNaoTransmitidas" action="#{uploadBean.getPossuiNotasFiscaisNaoTransmitidas}"
data="#{uploadBean.questionarAbaNotasFiscais}" oncomplete="questionarAbaNotasFiscais = data; console.timeEnd('consulta');console.info('servidor retornou ' + questionarAbaNotasFiscais)"
immediate="true" process="tab-10" ajaxSingle="true" reRender="tab-10"/>
<a4j:loadScript src="../../js/orcamentoVistoria.js"/>
<rich:tabPanel id="abas" switchType="ajax" >
<!-- many tabs... -->
<rich:tab
id="tab-10"
name="tab-10"
ontabenter="return prosseguirAbaNotasFiscais();"
ontableave="return prosseguirAbaNotasFiscais();" >
<!-- content -->
</rich:tab>
</rich:tabPanel>
Java脚本
var questionarAbaNotasFiscais = null;
function prosseguirAbaNotasFiscais() {
// questionarAbaNotasFiscais = null;
console.info("prosseguirAbaNotasFiscais: Entrando");
console.time("consulta");
var b = possuiNotasFiscaisNaoTransmitidas();
console.info("prosseguirAbaNotasFiscais: Esperando retorno. b = " + b);
console.time("watingReturn")
while(typeof questionarAbaNotasFiscais === null) {
// wait for return
}
console.timeEnd("watingReturn")
console.info("prosseguirAbaNotasFiscais: respostaServidor? " + questionarAbaNotasFiscais);
var result = questionarAbaNotasFiscais ? confirm(msgNotasNaoTransmitidas): true;
console.info("prosseguirAbaNotasFiscais: Resultado? " + result);
questionarAbaNotasFiscais = null;
return result;
}
我想要的内容:prosseguirAbaNotasFiscais()
函数调用possuiNotasFiscaisNaoTransmitidas()
并等待全局变量questionarAbaNotasFiscais
填入oncomplete
并继续等待。一旦在此声明中和prosseguirAbaNotasFiscais()
函数questionarAbaNotasFiscais
结束时始终将其设置为null
,则等待总是执行上面的循环,仅在oncomplete
结束时结束执行。
我得到了什么:执行prosseguirAbaNotasFiscais()
时,调用服务器功能,但显然没有等待服务器返回。我观察到,首先调用JS函数,重新加载页面,然后调用服务器函数。
好的,服务器功能是异步执行的。那么有没有办法强制等到服务器运行?
谢谢,
Rafael Afonso
答案 0 :(得分:0)
var serverResponse = possuiNotasFiscaisNaoTransmitidas();
这不起作用,JavaScript方法无法直接在服务器上执行方法并返回结果。 a4j:jsFunction
做的是向服务器发送AJAX请求,然后服务器发回响应。它是异步的,所以是的,页面没有在服务器上等待(如果这样做会很糟糕)。
不是从bean方法返回结果而是将结果保存到bean属性,而是使用@data:
<a4j:jsFunction data="#{bean.result}"
name="possuiNotasFiscaisNaoTransmitidas"
oncomplete="if (data) {doSomething();}"
… />
&#34; oncomplete&#34;代码将在响应从服务器返回时执行。
我不确定结果值是否会直接在data
变量中,最好使用console.log
进行检查。