在非ajax调用中在客户端执行JavaScript

在非ajax调用中在客户端执行JavaScript,javascript,ajax,jsf-2,primefaces,callback,Javascript,Ajax,Jsf 2,Primefaces,Callback,在我的应用程序中,用户可以按下按钮创建和下载文件。这个过程需要一些时间,所以我想在此过程中阻止UI,直到出现下载窗口 <script type="text/javascript"> function start() { PF('crBui').show(); } function stop() { PF('crBui').hide(); } </script> 我正在处理响应的操作方法基本上如下所示: public void download() {

在我的应用程序中,用户可以按下按钮创建和下载文件。这个过程需要一些时间,所以我想在此过程中阻止UI,直到出现下载窗口

<script type="text/javascript">
function start() {
    PF('crBui').show();
}

function stop() {
    PF('crBui').hide();
}
</script>
我正在处理响应的操作方法基本上如下所示:

public void download() {
    FacesContext facesContext = FacesContext.getCurrentInstance();
    ExternalContext externalContext = facesContext.getExternalContext();
    // set content disposition etc.    
    XSSFWorkbook wb = getWorkbook();
    wb.write(externalContext.getResponseOutputStream());            
    facesContext.responseComplete();
}
<p:commandButton value="Doanload" id="b" 
                 action="#{bean.doanload()}"
                 ajax="false" 
                 onclick="PF('crBui').show();"  />
<p:blockUI block=":trGrid" widgetVar="crBui" trigger="b">
     <p:graphicImage value="/images/loading.gif" alt="loading..."/>
</p:blockUI>
<script type="text/javascript">
function start() {
    PF('crBui').show();
}

function stop() {
    PF('crBui').hide();
}
</script>
在我的JSF视图中,我触发了一个blockUI组件来禁用按钮,如下所示:

public void download() {
    FacesContext facesContext = FacesContext.getCurrentInstance();
    ExternalContext externalContext = facesContext.getExternalContext();
    // set content disposition etc.    
    XSSFWorkbook wb = getWorkbook();
    wb.write(externalContext.getResponseOutputStream());            
    facesContext.responseComplete();
}
<p:commandButton value="Doanload" id="b" 
                 action="#{bean.doanload()}"
                 ajax="false" 
                 onclick="PF('crBui').show();"  />
<p:blockUI block=":trGrid" widgetVar="crBui" trigger="b">
     <p:graphicImage value="/images/loading.gif" alt="loading..."/>
</p:blockUI>
<script type="text/javascript">
function start() {
    PF('crBui').show();
}

function stop() {
    PF('crBui').hide();
}
</script>
如果我使用ajax调用而不是非ajax调用,那么文件下载将不再有效

<script type="text/javascript">
function start() {
    PF('crBui').show();
}

function stop() {
    PF('crBui').hide();
}
</script>
有什么建议吗?我该如何归档我的功能?

您应该使用,而不是尝试创建一些homebrewn解决方案。showcase中的修改示例:

<script type="text/javascript">
function start() {
    PF('crBui').show();
}

function stop() {
    PF('crBui').hide();
}
</script>
xhtml:

<script type="text/javascript">
function start() {
    PF('crBui').show();
}

function stop() {
    PF('crBui').hide();
}
</script>

函数start(){
PF('crBui').show();
}
函数停止(){
PF('crBui').hide();
}
Bean:

<script type="text/javascript">
function start() {
    PF('crBui').show();
}

function stop() {
    PF('crBui').hide();
}
</script>
import java.io.InputStream;
import javax.faces.bean.ManagedBean;
import javax.faces.context.FacesContext;
import javax.servlet.ServletContext;

import org.primefaces.model.DefaultStreamedContent;
import org.primefaces.model.StreamedContent;

@ManagedBean
public class FileDownloadView {

    private StreamedContent file;

    public FileDownloadView() {       
        InputStream stream = <create your stream>
        file = new DefaultStreamedContent(stream, "<your mime-type>", "<your filename>");
    }

    public StreamedContent getFile() {
        return file;
    }
}
import java.io.InputStream;
导入javax.faces.bean.ManagedBean;
导入javax.faces.context.FacesContext;
导入javax.servlet.ServletContext;
导入org.primefaces.model.DefaultStreamedContent;
导入org.primefaces.model.StreamedContent;
@ManagedBean
公共类文件下载视图{
私有流内容文件;
公共文件下载视图(){
输入流=
文件=新的默认流内容(流“,”);
}
公共流内容getFile(){
返回文件;
}
}
您应该使用,而不是尝试创建一些自制解决方案。showcase中的修改示例:

<script type="text/javascript">
function start() {
    PF('crBui').show();
}

function stop() {
    PF('crBui').hide();
}
</script>
xhtml:

<script type="text/javascript">
function start() {
    PF('crBui').show();
}

function stop() {
    PF('crBui').hide();
}
</script>

函数start(){
PF('crBui').show();
}
函数停止(){
PF('crBui').hide();
}
Bean:

<script type="text/javascript">
function start() {
    PF('crBui').show();
}

function stop() {
    PF('crBui').hide();
}
</script>
import java.io.InputStream;
import javax.faces.bean.ManagedBean;
import javax.faces.context.FacesContext;
import javax.servlet.ServletContext;

import org.primefaces.model.DefaultStreamedContent;
import org.primefaces.model.StreamedContent;

@ManagedBean
public class FileDownloadView {

    private StreamedContent file;

    public FileDownloadView() {       
        InputStream stream = <create your stream>
        file = new DefaultStreamedContent(stream, "<your mime-type>", "<your filename>");
    }

    public StreamedContent getFile() {
        return file;
    }
}
import java.io.InputStream;
导入javax.faces.bean.ManagedBean;
导入javax.faces.context.FacesContext;
导入javax.servlet.ServletContext;
导入org.primefaces.model.DefaultStreamedContent;
导入org.primefaces.model.StreamedContent;
@ManagedBean
公共类文件下载视图{
私有流内容文件;
公共文件下载视图(){
输入流=
文件=新的默认流内容(流“,”);
}
公共流内容getFile(){
返回文件;
}
}

我最终使用了PrimeFaces的PrimeFaces.monitorDownload()

<script type="text/javascript">
function start() {
    PF('crBui').show();
}

function stop() {
    PF('crBui').hide();
}
</script>
我认为:

<script type="text/javascript">
function start() {
    PF('crBui').show();
}

function stop() {
    PF('crBui').hide();
}
</script>
<p:commandButton value="Doanload" id="b" 
             action="#{bean.doanload()}"
             ajax="false" 
             onclick="PrimeFaces.monitorDownload(start, stop);"  />

<script type="text/javascript">
    function start() {
        PF('crBui').show();
    }
    function stop() {
        PF('crBui').hide();
    }
</script>

函数start(){
PF('crBui').show();
}
函数停止(){
PF('crBui').hide();
}
让DownloadMonitor工作的主要技巧是在响应中简单地设置Cookie:

<script type="text/javascript">
function start() {
    PF('crBui').show();
}

function stop() {
    PF('crBui').hide();
}
</script>
externalContext.addResponseCookie(
    org.primefaces.util.Constants.DOWNLOAD_COOKIE,
    "true",
    Collections.<String, Object>emptyMap()
);
externalContext.addResponseCookie(
org.primefaces.util.Constants.DOWNLOAD_COOKIE,
“真的”,
Collections.emptyMap()
);

这样,UI元素将被阻止,直到出现文件下载窗口,这正是我最终想要实现的。

我最终使用了PrimeFaces的PrimeFaces.monitorDownload()

<script type="text/javascript">
function start() {
    PF('crBui').show();
}

function stop() {
    PF('crBui').hide();
}
</script>
我认为:

<script type="text/javascript">
function start() {
    PF('crBui').show();
}

function stop() {
    PF('crBui').hide();
}
</script>
<p:commandButton value="Doanload" id="b" 
             action="#{bean.doanload()}"
             ajax="false" 
             onclick="PrimeFaces.monitorDownload(start, stop);"  />

<script type="text/javascript">
    function start() {
        PF('crBui').show();
    }
    function stop() {
        PF('crBui').hide();
    }
</script>

函数start(){
PF('crBui').show();
}
函数停止(){
PF('crBui').hide();
}
让DownloadMonitor工作的主要技巧是在响应中简单地设置Cookie:

<script type="text/javascript">
function start() {
    PF('crBui').show();
}

function stop() {
    PF('crBui').hide();
}
</script>
externalContext.addResponseCookie(
    org.primefaces.util.Constants.DOWNLOAD_COOKIE,
    "true",
    Collections.<String, Object>emptyMap()
);
externalContext.addResponseCookie(
org.primefaces.util.Constants.DOWNLOAD_COOKIE,
“真的”,
Collections.emptyMap()
);

这样,UI元素将被阻止,直到出现文件下载窗口,这正是我最终想要实现的。

感谢您的回答,如果我只想从服务器下载文件,“p:FileDownload”组件确实是件好事。但在我的情况下,ApachePOI库的工作方式与我直接写入OutputStream的方式相同,但StreamedContent只接受InputStream。我查看了PrimeFaces的源代码,发现它与我在代码中所做的几乎相同。因此,在这里使用PF组件,我最终会将文件写入ByteArrayOutputStream,然后再将其写入ByteInputStream,只需逐字节。。。只是让PF组件再次将其逐字节写入OutputSteam。听起来很难听。但是现在我了解了DownloadMonitor的工作原理,现在我可以不用p:fileDownload就可以使用它了。再次感谢你指出p:download的可能性,它让我朝着正确的方向前进:)谢谢你的回答,如果我只想从服务器下载一个文件,“p:fileDownload”组件确实是件好事,ApachePOI库的工作方式与我直接写入OutputStream的方式相同,但StreamedContent只接受InputStream。我查看了PrimeFaces的源代码,发现它与我在代码中所做的几乎相同。因此,在这里使用PF组件,我最终会将文件写入ByteArrayOutputStream,然后再将其写入ByteInputStream,只需逐字节。。。只是让PF组件再次将其逐字节写入OutputSteam。听起来很难听。但是现在我了解了DownloadMonitor的工作原理,现在我可以不用p:fileDownload就可以使用它了。因此再次感谢您通过p:download指出了这种可能性,它将我推向了正确的方向:)您的代码帮助我在
ajax=“false”
中使用了
commandbutton
,但是为什么我需要使用
org.primefaces.util.Constants.DOWNLOAD_COOKIE
?您的代码帮助我使用
commandbutton
ajax=“false”
,但是为什么我需要使用
org.primefaces.util.Constants.DOWNLOAD_COOKIE
<script type="text/javascript">
function start() {
    PF('crBui').show();
}

function stop() {
    PF('crBui').hide();
}
</script>