CreateAction

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

Действие реализовано классом io.jmix.ui.action.list.CreateAction и объявляется в XML с помощью атрибута type="create". Общие свойства действий можно конфигурировать с помощью атрибутов элемента action, подробнее см. раздел Декларативные действия. Ниже рассматриваются параметры, специфичные для класса CreateAction.

Параметры

Следующие параметры можно установить и в XML, и в Java:

  • openMode - режим открытия экрана редактирования, задаваемый значением перечисления OpenMode: NEW_TAB, DIALOG, и т.д. По умолчанию экран открывается в режиме THIS_TAB.

  • screenId - строковый идентификатор экрана редактирования. По умолчанию используется экран, аннотированный @PrimaryEditorScreen, или имеющий идентификатор вида <entity_name>.edit, например demo_Order.edit.

  • screenClass - класс Java экрана редактирования. Данный параметр имеет более высокий приоритет, чем screenId.

Например, если необходимо открыть определенный экран редактирования в режиме диалога, действие можно сконфигурировать в XML следующим образом:

<action id="create" type="create">
    <properties>
        <property name="openMode" value="DIALOG"/>
        <property name="screenClass" value="ui.ex1.screen.entity.customer.CustomerEdit"/>
    </properties>
</action>

В качестве альтернативы, действие можно инжектировать в контроллер экрана и сконфигурировать, используя сеттеры:

@Named("customersGroupTable.create")
private CreateAction<Customer> createAction;

@Subscribe
public void onInit(InitEvent event) {
    createAction.setOpenMode(OpenMode.DIALOG);
    createAction.setScreenClass(CustomerEdit.class);
}

Обработчики

Далее рассматриваются параметры, которые можно сконфигурировать только программно в Java. Для генерации корректно аннотированных методов для этих параметров используйте Studio.

screenOptionsSupplier

Это обработчик, возвращающий объект ScreenOptions для передачи в открываемый экран редактирования. Например:

@Install(to = "custTable.create", subject = "screenOptionsSupplier")
private ScreenOptions custTableCreateScreenOptionsSupplier() {
    return new MapScreenOptions(ParamsMap.of("someParameter", 10));
}

Возвращаемый объект ScreenOptions будет доступен в InitEvent открываемого экрана.

screenConfigurer

Это обработчик, принимающий экран редактирования для его конфигурации перед открытием. Например:

@Install(to = "custTable.create", subject = "screenConfigurer")
private void custTableCreateScreenConfigurer(Screen screen) {
    ((CustomerEdit) screen).setSomeParameter(10);
}

Обратите внимание, что конфигуратор экрана вступает в действие, когда экран уже инициализирован, но еще не показан, то есть после InitEvent и AfterInitEvent, и до BeforeShowEvent.

newEntitySupplier

Это обработчик, возвращающий новый экземпляр сущности для отображения в экране редактирования. Например:

@Install(to = "custTable.create", subject = "newEntitySupplier")
private Customer custTableCreateNewEntitySupplier() {
    Customer customer = metadata.create(Customer.class);
    customer.setFirstName("Sean");
    customer.setLastName("White");
    return customer;
}

initializer

Это обработчик, принимающий новый экземпляр для его инициализации перед отображением в экране редактирования. Например:

@Install(to = "custTable.create", subject = "initializer")
private void custTableCreateInitializer(Customer customer) {
    customer.setFirstName("Abel");
    customer.setLastName("Higgins");
}

transformation

Это обработчик, вызываемый после того, как сущность выбрана и прошла валидацию в экране редактирования. Он принимает выбранную сущность и может быть использован для того, чтобы преобразовать закоммиченную сущность перед ее установкой в целевой контейнер данных. Например:

@Install(to = "custTable.create", subject = "transformation")
private Customer custTableCreateTransformation(Customer customer) {
    return reloadCustomer(customer);
}

afterCommitHandler

Это обработчик, вызываемый после коммита созданного экземпляра сущности в экране редактирования. Принимает созданную сущность. Например:

@Install(to = "custTable.create", subject = "afterCommitHandler")
private void custTableCreateAfterCommitHandler(Customer customer) {
    System.out.println("Created " + customer);
}

afterCloseHandler

Это обработчик, вызываемый после закрытия экрана редактирования. Принимает AfterCloseEvent. Например:

@Install(to = "custTable.create", subject = "afterCloseHandler")
private void custTableCreateAfterCloseHandler(AfterCloseEvent afterCloseEvent) {
    if (afterCloseEvent.closedWith(StandardOutcome.COMMIT)) {
        System.out.println("Committed");
    }
}

Использование ActionPerformedEvent

Для того чтобы произвести какие-либо проверки, или взаимодействовать с пользователем перед выполнением действия, необходимо подписаться на событие ActionPerformedEvent действия и в нужный момент вызвать метод execute(). Действие будет вызвано со всеми параметрами, которые были для него заданы. В примере ниже перед выполнением действия отображается диалог подтверждения:

@Named("custTable.create")
private CreateAction<Customer> custTableCreate;

@Subscribe("custTable.create")
public void onCustTableCreate(Action.ActionPerformedEvent event) {
    dialogs.createOptionDialog()
            .withCaption("Please confirm")
            .withMessage("Do you really want to create new customer?")
            .withActions(
                    new DialogAction(DialogAction.Type.YES)
                            .withHandler(e -> custTableCreate.execute()), // execute action
                    new DialogAction(DialogAction.Type.NO)
            )
            .show();
}

Можно также подписаться на ActionPerformedEvent, и вместо вызова метода execute() действия, использовать для открытия экрана выбора ScreenBuilders API напрямую. По сути, в этом случае все специфичные параметры действия игнорируются, и действуют только общие параметры: caption, icon, и т.д. Например:

@Subscribe("customersTable.create")
public void onCustomersTableCreate(Action.ActionPerformedEvent event) {
    screenBuilders.editor(customersTable)
            .newEntity()
            .withOpenMode(OpenMode.DIALOG)
            .withScreenClass(CustomerEdit.class)
            .withAfterCloseListener(afterScreenCloseEvent -> {
                if (afterScreenCloseEvent.closedWith(StandardOutcome.COMMIT)) {
                    Customer committedCustomer = (afterScreenCloseEvent.getSource()).getEditedEntity();
                    System.out.println("Created " + committedCustomer);
                }
            })
            .build()
            .show();
}