Показать и скрыть 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.

Другие вопросы по тегам