Недавно, работая над новыми диаграммами и диаграммой «Служба экспорта» в 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 exampleFacesContext.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> |
Если куки отключены, то, конечно, ничего не отображается, но обычно это редкий случай.