4.3.2. Передача параметров в экран
Передача параметров из одного экрана в другой является одной из самых частых задач в разработке UI. Рассмотрим типовые решения этой задачи на примере демо-приложения "управление заказами".
- При открытии экрана методом openWindow
-
Параметры могут быть переданы в мэп, являющейся опциональным параметром методов
openWindow()
,openLookup()
иopenEditor()
. Они будут доступны в открываемом экране в виде мэп, передаваемой в метод init(), а также индивидуально, если они инжектируются с помощью аннотации @WindowParam.Предположим, что мы хотим отфильтровать список продуктов в экране просмотра сущности Product, передав в него некоторые параметры из экрана редактирования сущности Order.
-
Экран редактирования OrderEdit содержит метод
addOrderLine()
, вызываемый действиемaddOrderLine
. Этот метод открывает экран выбора продукта, передавая в него два параметра:-
текущий выбранный покупатель,
-
список уже добавленных продуктов.
Когда пользователь выбирает продукт, открывается экран QuantityDialog, где пользователь вводит количество единиц выбранного продукта. После закрытия этого экрана создаётся новый экземпляр сущности OrderLine и затем добавляется в таблицу строк заказа.
openLookup("sample$Product.browse", items -> { if (!items.isEmpty()) { openQuantityDialog((Product) items.iterator().next()); } }, WindowManager.OpenType.THIS_TAB, ParamsMap.of( "customer", getItem().getCustomer(), "added", orderLinesDs.getItems().stream() .map(line -> line.getProduct().getId()) .collect(Collectors.toList()) ) );
-
-
Экран просмотра ProductBrowse изменяет свой источник данных в зависимости от переданного покупателя. Если покупатель передан, в таблице отображаются только продукты, имеющие ссылку на этого покупателя либо не связанные ни с одним покупателем. Параметры инжектируются в контроллер экрана с помощью аннотации @WindowParam:
@WindowParam private Customer customer; @Override public void init(Map<String, Object> params) { if (customer != null) { productsDs.setQuery( "select e from sample$Product e left join e.customer c " + "where c.id = :param$customer or c is null"); } }
Также, когда экран выбора продукта открывается для создания строк заказа, в нём программно создаётся и применяется фильтр, который отображает только те продукты, которые ещё не были использованы в этом заказе.
Tip@WindowParam private List<UUID> added; @Override public void ready() { if (added != null && !added.isEmpty()) { FilterEntity filterEntity = metadata.create(FilterEntity.class); filterEntity.setName("Not added yet"); filterEntity.setXml("<filter>\n" + " <and>\n" + " <c name=\"id\" class=\"java.util.UUID\" inExpr=\"true\" hidden=\"true\" operatorType=\"NOT_IN\" width=\"1\" type=\"PROPERTY\">" + " <![CDATA[((e.id not in :component$filter.id_list) or (e.id is null)) ]]>\n" + " <param name=\"component$filter.id_list\" javaClass=\"java.util.UUID\">NULL</param>\n" + " </c>\n" + " </and>\n" + "</filter>"); filter.setFilterEntity(filterEntity); filter.setParamValue("id_list", added); filter.apply(true); } }
Содержимое атрибута
FilterEntity.xml
может быть взято из фильтра, созданного при работе приложения: откройте Entity Inspector, найдите созданный фильтр, сохраненный как экземпляр сущностиsec$Filter
, и скопируйте его XML.
-
- При открытие экранов из PickerField
-
Компонент PickerField и компоненты, его расширяющие, также могут передавать параметры в открываемые экраны. Параметры задаются для действий PickerField:
LookupAction
иOpenAction
.Допустим, мы хотим изменять заголовок экрана выбора сущности Customer, если он был открыт из компонента
PickerField
в экране редактирования сущности Product.-
В экране ProductEdit мы указываем параметры для действия
PickerField
LookupAction, используя методsetLookupScreenParams()
:public class ProductEdit extends AbstractEditor<Product> { @Named("fieldGroup.customer") private PickerField customerField; @Override protected void postInit() { customerField.getLookupAction().setLookupScreenParams(ParamsMap.of("product", getItem())); } }
-
Затем мы инжектируем переданные параметры в экране CustomerBrowse:
@WindowParam private Product product; @Override public void init(Map<String, Object> params) { if (product != null && product.getName() != null) { getFrame().setCaption("Select a customer for " + product.getName()); } }
Теперь, если экран выбора покупателя открывается из редактора продукта, мы сразу можем увидеть, что это за продукт.
-