Показать и скрыть p:blockUI в управляемом бине
У меня есть страница с 2 раскрывающимися списками (мы позвоним, затем сбросим 1 и сбросим 2). Когда пользователь выбирает что-то из drop 1, у меня есть метод, который вызывается и запускает запрос, который будет заполнять drop 2, основываясь на том, что такое drop 1. Что мне нужно сделать, это заблокировать пользовательский интерфейс при изменении drop 1, а затем разблокировать его, когда запрос вернулся и заполнить drop 2. У меня есть заглушка, как я думаю, что он должен работать, но не уверен, как получить доступ к пользовательскому интерфейсу блока из кода.
public void onPrimaryQueryDataSourceChanged() {
// ** Block UI **
try {
// Run query, get results, and populate dropdown
} catch (SQLException e) {
e.printStackTrace();
} finally {
// ** Unblock UI **
}
}
Как мне этого добиться?
1 ответ
концепция
Вы не можете показать blockUI в коде Java.
Вы можете показать blockUI в скрипте JS.
Вы можете указать JS-скрипт в java-коде для запуска после завершения ответа.
Чтобы указать JS-скрипт в Java-коде для запуска после завершения ответа, PrimeFaces предлагает утилиту RequestContext с функцией execute(String script)
- выполняет скрипт после завершения ajax-запроса или при загрузке страницы.
Проблема с предполагаемой заглушкой
Давайте посмотрим на вашу заглушку:
public void onPrimaryQueryDataSourceChanged() {
// ** Block UI **
// To show blockUI you may write the following:
RequestContext.getCurrentInstance().execute("PF('myBlockUI').show();");
// Note that even it is called "execute"
// script "PF('myBlockUI').show();" will be executed AFTER RESPONSE COMPLETE.
// So here you need to return.
// Then the response with included JS script to show blockUI will be send.
// Then client retrieves the response and runs your JS script.
// Then JS script shows blockUI.
// So the remaining code below is misplaced.
try {
// Run query, get results, and populate dropdown
} catch (SQLException e) {
e.printStackTrace();
} finally {
// ** Unblock UI **
}
Решение
Аякс имеет базовую технику для вашего случая. Вы можете использовать:
onstart // здесь вы показываете blockUI
само действие (запрос ajax) // здесь на стороне сервера вы вводите значения для выпадающего списка
oncomplete // здесь вы скрываете blockUI
Бетонный раствор
Просто смешайте примеры из PrimeFaces Showcase: http://www.primefaces.org/showcase/ui/ajax/dropdown.xhtml http://www.primefaces.org/showcase/ui/misc/blockUI.xhtml
Таким образом, вы можете написать следующее:
<h:panelGrid id="panelGridId" columns="2" cellpadding="5">
<p:outputLabel for="country" value="Country: " />
<p:selectOneMenu id="country" value="#{dropdownView.country}">
<p:ajax event="change" listener="#{dropdownView.onCountryChange}"
update="city" onstart="PF('myBlockUI').show()"
oncomplete="PF('myBlockUI').hide()" />
<f:selectItem itemLabel="Select Country" itemValue=""
noSelectionOption="true" />
<f:selectItems value="#{dropdownView.countries}" />
</p:selectOneMenu>
<p:outputLabel for="city" value="City: " />
<p:selectOneMenu id="city" value="#{dropdownView.city}">
<f:selectItem itemLabel="Select City" itemValue=""
noSelectionOption="true" />
<f:selectItems value="#{dropdownView.cities}" />
</p:selectOneMenu>
<p:blockUI block="panelGridId" widgetVar="myBlockUI" />
</h:panelGrid>
где onCountryChange
- функция, где вы населяете cities
для выпадающего города.
Такое поведение является распространенным случаем, поэтому PrimeFaces предлагает декларативный способ отображения blockUI с инкапсулированными сценариями onstart и oncomplete:
<p:blockUI block="panelGridId" trigger="country" />
где trigger
список идентификаторов компонентов, которые ajax-запросы запускают для показа blockUI.