简体   繁体   English

<a4j:jsFunction>调用从服务器返回未定义

[英]<a4j:jsFunction> calling returns undefined from server

In my Managed Bean, I have a simple boolean method: 在我的Managed Bean中,我有一个简单的布尔方法:

public class UploadBean {

    // ...

    public boolean getPossuiNotasFiscaisNaoTransmitidas() {
        boolean result = false;

        // Some computation ...

        return result;
    }

}

In my XHTML page, I am using RichFaces 3.3.3 tabPanel. 在我的XHTML页面中,我正在使用RichFaces 3.3.3 tabPanel。 In a specific tab I need make a confirmation to see if I really open it or not: 在特定的标签中,我需要进行确认以查看是否确实打开了它:

    <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>

The function prosseguirAbaNotasFiscais() in orcamentoVistoria.js calls the managed bean method: 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;
}

What I expected : when I enter (or leave) in the tab, the page will call the managed bean method. 我的期望 :当我在选项卡中输入(或离开)时,页面将调用托管bean方法。 If its answer was true, it will be asked to the user if she wants to continue to enter/leave. 如果答案是正确的,则将询问用户是否要继续输入/离开。 If its answer was false, so the tab will be directly entered/left. 如果答案为假,则将直接输入/退出该标签。

What I really got : when I enter (or leave) in the tab, the page apparently calls the managed bean method. 我真正得到的是 :当我在选项卡中输入(或离开)时,该页面显然会调用托管bean方法。 At least, in debug, I can see the method being executed (many times, actually). 至少在调试中,我可以看到该方法正在执行(实际上是很多次)。 However, in the JS return ( LOG 2 line), the serverResponse variable is undefined. 但是,在JS返回( LOG 2行)中, serverResponse变量未定义。 It is like the page was not waiting for the server response. 就像页面没有在等待服务器响应一样。 Consequently the JS function will always return true and the tab always will be directly entered/left. 因此,JS函数将始终返回true ,并且选项卡将始终直接输入/离开。

So, What should I do? 所以我该怎么做? Is it some specific attribute in <a4j:jsFunction> tag? <a4j:jsFunction>标记中的某些特定属性吗?

Thanks 谢谢

Rafael Afonso 拉斐尔·阿方索(Rafael Afonso)

UPDATE 17/02/2016 更新17/02/2016

@Makhiel, thanks for your suggestion. @Makhiel,感谢您的建议。 However, what I need is that by some way, after the execution of oncomplete , allow or not the tab change. 但是,我需要以某种方式在执行oncomplete ,允许或不更改选项卡。 But (at least from I could understand), it is possible only through ontabenter or ontableave from tab. 但是(至少据我所知),只有通过ontabenterontableave可能。

Following the Makhiel suggestion, I did the following suggestions in my code: 根据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: 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 Script 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;
}

What I want : prosseguirAbaNotasFiscais() function calls possuiNotasFiscaisNaoTransmitidas() and wait until the global variable questionarAbaNotasFiscais is filled in oncomplete and proceed as waited. 我想什么prosseguirAbaNotasFiscais()函数调用possuiNotasFiscaisNaoTransmitidas()并等待,直到全局变量questionarAbaNotasFiscais填充oncomplete并继续为等待。 Once that in this declaration and at the end of prosseguirAbaNotasFiscais() function questionarAbaNotasFiscais is always setted to null , It is waited that always execute the loop above, finishing only when oncomplete be executed. 一旦在此声明,在年底prosseguirAbaNotasFiscais()函数questionarAbaNotasFiscais总是设置好的到null ,则等待始终执行上述循环,当仅完成oncomplete被执行。

What I got : When prosseguirAbaNotasFiscais() is executed, calls the server function, but apparently is not waiting by server return. 我得到的是 :当执行prosseguirAbaNotasFiscais() ,调用服务器函数,但是显然不等待服务器返回。 I observed that first the JS function is called, the page is reloaded and just then the server function is called. 我观察到,首先调用JS函数,然后重新加载页面,然后再调用服务器函数。

Ok, the server function is executed async. 好的,服务器功能是异步执行的。 So Is there some way to force to wait until the server function? 那么,是否有某种方法可以强制等待服务器运行?

Thanks, 谢谢,

Rafael Afonso 拉斐尔·阿方索(Rafael Afonso)

var serverResponse = possuiNotasFiscaisNaoTransmitidas();

This will not work, a JavaScript method cannot directly execute a method on the server and give you back the result. 这将无法正常工作,JavaScript方法无法直接在服务器上执行方法并将结果退还给您。 What a4j:jsFunction does is send an AJAX request to the server and then the server sends back a response. a4j:jsFunction所做的是向服务器发送AJAX请求,然后服务器发回响应。 It is asynchronous so yes the page is not waiting on the server (it would be bad if it did). 它是异步的,因此页面没有在服务器上等待(如果这样做的话,那将是很糟糕的)。

Instead of the returning a result from the bean method you save the result to a bean property, then you use @data: 将结果保存到bean属性中,而不是从bean方法中返回结果,而是使用@data:

<a4j:jsFunction data="#{bean.result}"
    name="possuiNotasFiscaisNaoTransmitidas" 
    oncomplete="if (data) {doSomething();}"
    … />

The "oncomplete" code will execute when the response comes back from the server. 从服务器返回响应时,将执行“未完成”代码。

I am not sure if the result value will be directly in the data variable, better check with console.log . 我不确定结果值是否直接在data变量中,最好用console.log检查。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM