在OmniFaces sendFile之后关闭PrimeFaces对话框

时间:2014-10-09 14:26:53

标签: jsf primefaces omnifaces

我正在尝试使用OmniFaces <p:ajaxstatus />函数下载文件时创建Faces.sendFile之类的指标。当用户单击“导出”链接时,会出现一个对话框,告诉他们正在创建文件(因为这可能需要一些时间,具体取决于数据大小),然后在文件下载后,消息将关闭。

在我的xhtml中:

<p:dialog widgetVar="excelDialog" modal="true">
    <h2>Building Spreadsheet</h2>
</p:dialog>

<h:commandLink value="Export" action="#{resultsBean.excelExport}" onclick="excelDialog.show();" />

并在我的ViewScoped bean中:

public void excelExport() throws IOException {
    ExcelExport ee = new ExcelExport(results);
    Faces.sendFile(ee.getFile(), true);
}

我无法想象的是如何在响应完成后关闭对话框。

我尝试过使用PrimeFaces RequestContext(适用于非ajax请求),但不起作用。我想知道这是否是因为Faces.sendFile在使用RequestContext之前调用FacesContext.responseComplete()

public void excelExport() throws IOException {
    ExcelExport ee = new ExcelExport(results);
    Faces.sendFile(ee.getFile(), true);
    RequestContext c = RequestContext.getCurrentInstance();        
    c.execute("PF('excelDialog').hide();");       
} 
  • JSF 2.1
  • PrimeFaces 4.0
  • OmniFaces 1.8

1 个答案:

答案 0 :(得分:4)

  

我想知道这是因为Faces.sendFile在使用RequestContext之前调用FacesContext.responseComplete()

它只是防止下载文件内容被破坏,因为其他东西试图将更多数据写入响应。

您基本上是在尝试针对单个请求发送多个回复。这是不可能的。每个请求只能发送一个响应。如果您的尝试成功,下载文件内容将被破坏,因为代表PrimeFaces ajax响应的某些XML代码将附加到下载文件内容的末尾。

您基本上需要发送2个请求,从而在第一个请求结束时自动触发第二个请求。第一个请求应该准备文件并将其停放在某处(@ViewScoped bean的属性?)然后关闭对话框并触发第二个请求。第二个请求应该只下载停放的文件。第一个请求可以像ajax一样完成<p:commandButton>,但第二个请求必须完全同步,原因很明显。您可以使用使用CSS隐藏的<h:commandLink>执行第二个请求。

E.g。

<h:form id="formId">
    <p:commandLink value="Export" action="#{resultsBean.excelExport}" 
        onclick="excelDialog.show();" 
        oncomplete="excelDialog.hide(); document.getElementById('formId:linkId').click();" />
    <h:commandLink id="linkId" action="#{resultsBean.excelDownload}" style="display:none;" />
</h:form>

private File excelFile;

public void excelExport() {
    excelFile= new ExcelExport(results).getFile();
}

public void excelDownload() throws IOException {
    Faces.sendFile(excelFile, true);
}