目的是在服务器准备下载文件时显示等待微调器图标。在我的用例中,我生成一个大型报告,在浏览器的下载/另存为提示被调用之前需要一些时间在服务器端。我可以向等待微调器显示没问题,但我找不到清除它的方法。
当前相关代码:
<h:commandButton id="generate" value="Generate Report" type="submit"
action="#{bean.generateReport()}"
onclick="#{rich:component('waitIcon')}.start();"/>
<a4j:status id="waitIcon">
<f:facet name="start">
<h:graphicImage value="/images/ai.gif" alt="ai" />
</f:facet>
</a4j:status>
bean.generateReport()
是一个需要1-10secs服务器端的操作,然后吐出下载响应。
这是使用richfaces a4j:状态指示器,因为它提供了有用的API,如.start()和.stop(),但它也可以是任何dom元素和设置可见性。问题是我无法抓住正确的事件。我需要捕捉像onresponsereceived ......
我尝试过的解决方案:
使用a4j:commandButton
提供oncomplete
事件,但该按钮会生成一个AJAX请求,该请求无法启动下载。 (见h:command button oncomplete action)
使用window.timeout
函数调用组件上的.stop()
。这在功能层面上起作用,但由于生成时间在1-10秒之间相当剧烈地摆动,因此它使指示器不能反映现实。
任何人对处理这个有什么好主意吗?
答案 0 :(得分:1)
一种方法是返回到您有条件地呈现启动实际下载的JS代码的同一页面。
<h:form>
...
<h:commandButton value="submit" action="#{bean.prepareFileForDownload}" />
<h:outputScript rendered="#{bean.fileReadyForDownload}">
// Do here your thing to indicate start of download.
window.location = '#{bean.fileDownloadURL}';
</h:outputScript>
</h:form>
另一种方法是每隔一段时间检查一次cookie。您只需要生成一个URL安全值作为某种下载令牌(System.currentTimeMillis()
完全适用于此)。
<h:form>
...
<input type="hidden" name="token" value="#{bean.token}" />
<h:commandButton value="submit" action="#{bean.downloadFile}" onclick="checkToken(this.form.token)" />
<h:outputScript>
function checkToken(token) {
var pollDownloadStart = setInterval(function() {
if (document.cookie.indexOf("download=" + token) > -1) {
document.cookie = "download=" + token + "; expires=" + new Date(0).toGMTString() + "; path=/";
clearInterval(pollDownloadStart);
// Do here your thing to indicate start of download.
}
}, 500);
}
</h:outputScript>
</h:form>
在downloadFile()
// Prepare download here.
// ...
// Once finished, set cookie and stream download to response.
Cookie cookie = new Cookie("download", token);
cookie.setPath("/");
response.addCookie(cookie);
// ...
答案 1 :(得分:0)
简单的解决方案是将setTimeout设置为1秒,以检查是否已收到响应。 setTimeout将重复直到清除。
所以你可以这样做:
var responseReceived, hTimer = setTimeout( function() {
if( responseReceived ) {
// code to stop/hide spinner here
clearTimeout( hTimer );
}
}, 1000 );
// responseReceived is set when the response is received
或者,您需要的是编程术语中所谓的彗星。根据您的需求,Ajax长期调查最适合您的需求。您基本上向服务器(异步)打开ajax请求,并且回调函数在服务器响应时执行您想要的任何操作。看看这些参考文献:
答案 2 :(得分:0)
如果我理解正确,您的用户会以格式填充一些数据,然后点击提交按钮,将 POST 数据发送到服务器然后处理它,一段时间后它会生成一个响应,触发“另存为...”对话框窗口。如果这是正确的,解决方案是创建隐藏的 iframe ,然后通过在目标上设置目标属性,将服务器的响应重定向到 iframe 表单,最后挂钩 iframe 的 onload 事件。