urlQueryParameters

Фасет urlQueryParameters предназначен для декларативной привязки состояния экрана к URL. Он позволяет сохранять состояние экрана при навигации между экранами и при обновлении страницы браузера.

Если всё состояние экрана берется из базы данных, как в случае экранов деталей сущности, для восстановления состояния достаточно идентификатора сущности в URL. Но если некоторые компоненты экрана содержат значения, которые не хранятся в базе данных, то для восстановления при переинициализации экрана их нужно закодировать в URL.

Очевидным примером такой необходимости является экран списка сущностей с пагинацией и фильтрацией. Параметры пагинации и фильтрации необходимо сохранить при обновлении страницы браузера и при переходе к экрану деталей и обратно.

Состояние экрана, закодированное в URL, также предоставляет глубокую ссылку, точно соответствующую тому, что отображается на экране.

Основное использование

Чтобы привязать параметры пагинации и фильтрации к URL, определите urlQueryParameters в экране и используйте вложенные элементы для соединения существующих компонентов по их идентификаторам. В следующем примере фасет urlQueryParameters используется с компонентами genericFilter и simplePagination:

<facets>
    <urlQueryParameters id="urlQueryParameters">
        <pagination component="pagination"/>
        <genericFilter component="genericFilter"/>
    </urlQueryParameters>
</facets>
<layout expand="usersTable">
    <genericFilter id="genericFilter"
                   dataLoader="usersDl">
        <properties include=".*"/>
    </genericFilter>
    <hbox id="buttonsPanel" classNames="buttons-panel">
        <!-- ... -->
        <simplePagination id="pagination" dataLoader="usersDl"/>
    </hbox>

В результате, фильтрация экрана списка сущностей User по атрибуту active и выбор второй страницы будут отображены в URL следующим образом:

http://localhost:8080/users?genericFilterCondition=property%3Aactive_equal_true&maxResults=50&firstResult=100

Вы можете просматривать и редактировать атрибуты фасета в Jmix Studio используя панель испектора Jmix UI.

Поддерживаемые компоненты

pagination

Вложенный элемент pagination позволяет подключить фасет urlQueryParameters к компоненту simplePagination.

Атрибуты элемента pagination:

  • component - идентификатор компонента пагинации для подключения.

  • firstResultParam - (необязательно) имя параметра запроса для начала текущей страницы.

  • maxResultsParam - (необязательно) имя параметра запроса для размера страницы.

propertyFilter

Вложенный элемент propertyFilter позволяет подключить фасет urlQueryParameters к компоненту propertyFilter.

Атрибуты элемента propertyFilter:

  • component - идентификатор компонента propertyFilter для подключения.

  • param - (необязательно) имя параметра запроса для значения фильтра.

genericFilter

Вложенный элемент genericFilter позволяет подключить фасет urlQueryParameters к компоненту genericFilter.

Атрибуты элемента genericFilter:

  • component - идентификатор компонента genericFilter для подключения.

  • conditionParam - (необязательно) имя параметра запроса для условий фильтра.

  • configurationParam - (необязательно) имя параметра запроса для выбранной конфигурации фильтра.

dataGridFilter

Вложенный элемент dataGridFilter позволяет привязать состояние фильтров по заголовкам колонок к параметрам запроса URL.

В следующем примере для всех колонок включена фильтрация, а состояние фильтров привязано к параметрам запроса URL:

<urlQueryParameters>
    <dataGridFilter component="usersDataGrid"/>
</urlQueryParameters>
<dataGrid id="usersDataGrid"
          width="100%"
          minHeight="20em"
          dataContainer="usersDc">
    <columns filterable="true">
        <column property="username"/>
        <column property="firstName"/>
        <column property="lastName"/>
        <column property="email"/>
        <column property="active"/>
    </columns>
</dataGrid>

Параметры запроса URL обновляются, когда пользователь применяет или сбрасывает фильтр по заголовку колонки. При открытии URL или обновлении страницы восстанавливаются операция и значение каждого фильтра.

Атрибуты элемента dataGridFilter:

  • component - идентификатор компонента dataGrid, фильтры по заголовкам колонок которого привязываются к параметрам запроса URL.

  • param - (необязательно) имя параметра запроса для применённых фильтров по заголовкам колонок. По умолчанию к идентификатору компонента добавляется суффикс Filter, например customersDataGridFilter.

groupDataGridFilter

Начиная с Jmix 3.1

Вложенный элемент groupDataGridFilter позволяет привязать состояние фильтров по заголовкам колонок groupDataGrid к параметрам запроса URL. Элемент предоставляется дополнением Grouping Data Grid, поэтому используйте пространство имён groupg, уже объявленное для groupDataGrid.

В следующем примере для всех колонок включена фильтрация, а состояние фильтров привязано к параметрам запроса URL:

<urlQueryParameters>
    <groupg:groupDataGridFilter component="customersDataGrid"/>
</urlQueryParameters>
<groupg:groupDataGrid id="customersDataGrid"
                      width="100%"
                      minHeight="20em"
                      dataContainer="customersDc">
    <groupg:groupBy>
        <groupg:columnRef key="grade"/>
    </groupg:groupBy>
    <groupg:columns filterable="true">
        <groupg:groupColumn header="Grade"/>
        <groupg:column property="firstName"/>
        <groupg:column property="lastName"/>
        <groupg:column property="email"/>
        <groupg:column property="country"/>
        <groupg:column property="grade"/>
    </groupg:columns>
</groupg:groupDataGrid>

Параметры запроса URL обновляются, когда пользователь применяет или сбрасывает фильтр по заголовку колонки. При открытии URL или обновлении страницы восстанавливаются операция и значение каждого фильтра. Формат сериализации такой же, как у dataGridFilter, поэтому одни и те же параметры запроса подходят для эквивалентных конфигураций dataGrid и groupDataGrid.

Атрибуты элемента groupDataGridFilter:

  • component - идентификатор компонента groupDataGrid, фильтры по заголовкам колонок которого привязываются к параметрам запроса URL.

  • param - (необязательно) имя параметра запроса для применённых фильтров по заголовкам колонок. По умолчанию к идентификатору компонента добавляется суффикс Filter, например customersGroupDataGridFilter.

Привязка пользовательского состояния

Фасет urlQueryParameters позволяет привязать любое пользовательское состояние экрана к URL.

Рассмотрим пример экрана с следующими компонентами:

<details id="sampleDetails" summaryText="Some details">
    <textField id="sampleTextField" datatype="string"/>
</details>

Предположим, что целью является сохранение состояния opened макета details и значения компонента textField.

Тогда нужно реализовать объект-связыватель и зарегистрировать его в фасете urlQueryParameters:

private static final String DETAILS_OPENED_URL_PARAM = "detailsOpened";
private static final String TEXT_URL_PARAM = "text";

@ViewComponent
private UrlQueryParametersFacet urlQueryParameters;

@ViewComponent
private JmixDetails sampleDetails;

@ViewComponent
private TypedTextField<String> sampleTextField;

private class SampleUrlQueryParametersBinder extends AbstractUrlQueryParametersBinder { (1)

    public SampleUrlQueryParametersBinder() { (2)
        sampleDetails.addOpenedChangeListener(event -> {
            boolean opened = event.isOpened();
            QueryParameters qp = new QueryParameters(ImmutableMap.of(DETAILS_OPENED_URL_PARAM,
                    opened ? Collections.singletonList("1") : Collections.emptyList()));
            fireQueryParametersChanged(new UrlQueryParametersFacet.UrlQueryParametersChangeEvent(this, qp));
        });

        sampleTextField.addValueChangeListener(event -> {
            String text = event.getValue();
            QueryParameters qp = new QueryParameters(ImmutableMap.of(TEXT_URL_PARAM,
                    text != null ? Collections.singletonList(text) : Collections.emptyList()));
            fireQueryParametersChanged(new UrlQueryParametersFacet.UrlQueryParametersChangeEvent(this, qp));
        });
    }

    @Override
    public void updateState(QueryParameters queryParameters) { (3)
        List<String> detailsOpenedStrings = queryParameters.getParameters().get(DETAILS_OPENED_URL_PARAM);
        if (detailsOpenedStrings != null) {
            sampleDetails.setOpened("1".equals(detailsOpenedStrings.get(0)));
        }

        List<String> textStrings = queryParameters.getParameters().get(TEXT_URL_PARAM);
        if (textStrings != null && !textStrings.isEmpty()) {
            sampleTextField.setValue(textStrings.get(0));
        }
    }

    @Override
    public Component getComponent() {
        return null;
    }
}

@Subscribe
public void onInit(final InitEvent event) {
    urlQueryParameters.registerBinder(new SampleUrlQueryParametersBinder()); (4)
}
1 - наследуйте класс-связыватель от базового класса AbstractUrlQueryParametersBinder.
2 - в конструкторе связывателя добавьте слушатели компонентов, которые будут вызывать метод fireQueryParametersChanged() связывателя при изменении состояния компонентов.
3 - в методе updateState() связывателя обновите состояние компонентов.
4 - создайте экземпляр связывателя и зарегистрируйте его в фасете urlQueryParameters при инициализации экрана.
Фасет urlQueryParameters использует класс QueryParameters из API Vaadin для отправки и приема параметров запроса.