Primefaces 下载文件时添加loading
下载实现: html可以用不同的标签来实现
// html 示例1
<h:commandLink>
<p:commandButton value="DownLoad"/>
<p:fileDownload value="#{bean.export()}"/>
</h:commandLink>
// html 示例2
<p:commandLink value="DownLoad" ajax="false" actionListener="#{bean.export()}"/>
// html 示例3
<p:commandButton value="Download" ajax="false">
<p:fileDownload value="#{bean.export()}"/>
</p:commandButton>
添加loading
方案分析:
- 在标签上添加
onstart
oncomplete
事件;发现这两个方法都是ajax
方式调用时才会触发的方法 - 在
onclick
中触发loading
,bean.export()
中结束时,执行js方法PrimeFaces.current().executeScript(" $('.loading').modal('hide');");
,关闭loading
;想象很美好,现实很残酷…
在bean.export()
中添加执行js时也不生效,猜测是 解析出的a标签在执行submit时刷新页面时导致js不执行 - 终于找到了
PrimeFaces.monitorDownload
,可是发现它依然无法关闭loading
,主要是stop
事件触发不到
查看monitorDownload
源码 ,setInterval
的停止条件是cookie
值为true
,则需要在下载结束阶段设置cookie
。
// PrimeFaces.monitorDownload源码
window.PrimeFaces.monitorDownload = function (start, complete, monitorKey) {
if (this.cookiesEnabled()) {
if (start) {
start();
}
var cookieName = monitorKey ? 'primefaces.download_' + monitorKey : 'primefaces.download';
window.downloadMonitor = setInterval(function () {
var downloadComplete = getCookieByName(cookieName);
// download完成(complete)时的触发条件
if (downloadComplete === 'true') {
if (complete) {
complete();
}
clearInterval(window.downloadMonitor);
PrimeFaces.setCookie(cookieName, null);
}
}, 1000);
}
}
最终方案
- 页面html代码
<p:commandButton value="Download" ajax="false" onclick="PrimeFaces.monitorDownload(start,stop,'downFile')">
<p:fileDownload value="#{bean.export()}" monitorKey="downFile"/>
</p:commandButton>
<script type="text/javascript">
function start() {
$('.loading').modal();
}
function stop() {
$('.loading').modal('hide');
}
</script>
- 当然,下载结束是在
bean.export()
中触发的,但此处执行html
中的stop
不生效。则使用java
代码添加cookie
在export
方法中添加下面代码即可:
/** java 添加cookie,根据PrimeFaces.monitorDownload源码确定:
* name与primefaces <p:fileDownload> 的 monitorKey 对应,拼接而得
* value为 字符串'true'
*/
HttpServletResponse response = (HttpServletResponse) facesContext
.getCurrentInstance().getExternalContext().getResponse();
// 在response时添加cookie
Cookie cookie = new Cookie("primefaces.download_downFile", "true");
response.addCookie(cookie);