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 - (необязательно) имя параметра запроса для выбранной конфигурации фильтра.

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

Фасет 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 для отправки и приема параметров запроса.