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

时间:2021-10-24 15:19:03

In my application the user is able to push a button to create and download a file. The process takes some time, so I want to block the UI during this process until the download window appears.

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

The action method were I am handling the response looks basically like this:

我处理响应的行动方法基本上是这样的

public void download() {
    FacesContext facesContext = FacesContext.getCurrentInstance();
    ExternalContext externalContext = facesContext.getExternalContext();
    // set content disposition etc.    
    XSSFWorkbook wb = getWorkbook();
    wb.write(externalContext.getResponseOutputStream());            
    facesContext.responseComplete();
}

In my JSF view I am triggering a blockUI component to disable the button like this:

在我的JSF视图中,我触发了一个blockUI组件来禁用如下按钮:

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

I tried to use the PrimeFaces RequestContext to execute some JavaScript to hide the blockUI component, but that does not work. The JavaScript is not executed:

我试图使用PrimeFaces RequestContext来执行一些JavaScript来隐藏blockUI组件,但这行不通。JavaScript没有执行:

    public void download() {
        FacesContext facesContext = FacesContext.getCurrentInstance();
        ExternalContext externalContext = facesContext.getExternalContext();
        // set content disposition etc.    
        XSSFWorkbook wb = getWorkbook();
        wb.write(externalContext.getResponseOutputStream());    
        RequestContext.getCurrentInstance()
                      .execute("PF('crBui').hide();");        
        facesContext.responseComplete();
    }

If I am using a ajax call instead of the non-ajax call, then the file download does not work any longer.

如果我使用的是ajax调用而不是非ajax调用,那么文件下载就不再工作了。

Any suggestions how could I archieve my functionality?

有什么建议可以归档我的功能吗?

2 个解决方案

#1


2  

I finally ended up using PrimeFaces 'PrimeFaces.monitorDownload()'

最后我使用了PrimeFaces的prime face . monitordownload ()

In my view:

在我看来:

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

The main trick to get the DownloadMonitor working is to simply set a Cookie in the response:

让DownloadMonitor起作用的主要技巧是在响应中设置一个Cookie:

externalContext.addResponseCookie(
    org.primefaces.util.Constants.DOWNLOAD_COOKIE,
    "true",
    Collections.<String, Object>emptyMap()
);

That way the UI-elements are blocked until the window for the FileDownload appears, which is exactly what I wanted to achieve in the very end.

这样,ui元素就会被阻塞,直到出现FileDownload窗口,这正是我最后想要实现的。

#2


1  

You should use p:fileDownload instead of trying to create some homebrewn solution. Modified example from the showcase:

您应该使用p:fileDownload而不是尝试创建一些homebrewn解决方案。从橱窗中修改的例子:

xhtml:

xhtml:

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

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

Bean:

豆:

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

#1


2  

I finally ended up using PrimeFaces 'PrimeFaces.monitorDownload()'

最后我使用了PrimeFaces的prime face . monitordownload ()

In my view:

在我看来:

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

The main trick to get the DownloadMonitor working is to simply set a Cookie in the response:

让DownloadMonitor起作用的主要技巧是在响应中设置一个Cookie:

externalContext.addResponseCookie(
    org.primefaces.util.Constants.DOWNLOAD_COOKIE,
    "true",
    Collections.<String, Object>emptyMap()
);

That way the UI-elements are blocked until the window for the FileDownload appears, which is exactly what I wanted to achieve in the very end.

这样,ui元素就会被阻塞,直到出现FileDownload窗口,这正是我最后想要实现的。

#2


1  

You should use p:fileDownload instead of trying to create some homebrewn solution. Modified example from the showcase:

您应该使用p:fileDownload而不是尝试创建一些homebrewn解决方案。从橱窗中修改的例子:

xhtml:

xhtml:

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

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

Bean:

豆:

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