Недавно, работая над новыми диаграммами и диаграммой «Служба экспорта» в JSF, я столкнулся с довольно распространенной проблемой. Когда вы выполняете долгосрочную задачу (действие), вы хотели бы показать диалоговое окно состояния «Пожалуйста, подождите …» в начале и закрыть это диалоговое окно в конце, когда приходит ответ. Это не проблема для запросов AJAX, но это проблема для запросов не AJAX, которые передают в браузер некоторый двоичный контент. Чтобы решить эту проблему, мы можем использовать ту же технику, что и, например, компонент FileDownload в PrimeFaces. Мы можем установить специальный cookie в ответ и периодически проверять этот cookie на стороне клиента, если он установлен. Когда этот файл cookie установлен, мы можем закрыть диалог перед открытием. Файл cookie может быть установлен в JSF как:
1
2
3
|
// set cookie to be able to ask it and close status dialog for example FacesContext.getCurrentInstance().getExternalContext().addResponseCookie( "cookie.chart.exporting" , "true" , Collections.<String, Object>emptyMap()); |
Кнопка Non AJAX выполняет функцию JavaScript, скажем, monitorExporting, с двумя параметрами, представляющими другие функции JavaScript, которые должны вызываться в начале и в конце жизненного цикла запроса / ответа.
1
2
|
< p:commandButton value = "Export to PNG" ajax = "false" action = "#{combiChartController.exportToPng}" onclick = "monitorExporting(start, stop)" /> |
PrimeFaces уже предоставляет методы, чтобы проверить, включены ли куки, чтобы получить и удалить их. Итак, мы можем написать
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
|
function monitorExporting(start, complete) { if (PrimeFaces.cookiesEnabled()) { if (start) { start(); } window.chartExportingMonitor = setInterval(function() { var exportingComplete = PrimeFaces.getCookie( 'cookie.chart.exporting' ); if (exportingComplete === 'true' ) { if (complete) { complete(); } clearInterval(window.chartExportingMonitor); PrimeFaces.setCookie( 'cookie.chart.exporting' , null ); } }, 150 ); } } |
Файл cookie периодически запрашивается с помощью setInterval (…). Запуск функции показывает диалоговое окно «Please wait…», а остановка функции закрывает его.
01
02
03
04
05
06
07
08
09
10
11
|
<script type= "text/javascript" > /* <![CDATA[ */ function start() { statusDialog.show(); } function stop() { statusDialog.hide(); } /* ]]> */ </script> |
Если куки отключены, то, конечно, ничего не отображается, но обычно это редкий случай.