3.5.5.2.13. ViewAction
ViewAction - действие с коллекцией, предназначенное для просмотра и редактирования экземпляров сущности. Оно открывает экран редактирования таким же образом, как EditAction, но делает все поля ввода нередактируемыми и запрещает действия, реализующие интерфейс Action.DisabledWhenScreenReadOnly
. Если необходимо дать пользователю возможность переключить экран в режим редактирования, добавьте в экран кнопку и свяжите ее с предопределенным действием enableEditing
:
<hbox id="editActions" spacing="true">
<button action="windowCommitAndClose"/>
<button action="windowClose"/>
<button action="enableEditing"/> <!-- this button is shown only when the screen is in read-only mode -->
</hbox>
Заголовок действия enableEditing
можно переопределить в главном пакете сообщений, используя ключ actions.EnableEditing
, или непосредственно в экране путем указания атрибута caption
у соответствующей кнопки.
Действие реализовано классом com.haulmont.cuba.gui.actions.list.ViewAction
и объявляется в XML с помощью атрибута type="view"
. Общие свойства действий можно конфигурировать с помощью атрибутов элемента action
, подробнее см. раздел Декларативное создание действий. Ниже рассматриваются параметры, специфичные для класса ViewAction
.
Следующие параметры можно установить и в XML и в Java:
-
openMode
- режим открытия экрана редактирования, задаваемый значением перечисленияOpenMode
:NEW_TAB
,DIALOG
, и т.д. По умолчанию экран открывается в режимеTHIS_TAB
. -
screenId
- строковый идентификатор экрана редактирования. По умолчанию используется экран, аннотированный@PrimaryEditorScreen
, или имеющий идентификатор вида<entity_name>.edit
, напримерdemo_Customer.edit
. -
screenClass
- класс Java экрана редактирования. Данный параметр имеет более высокий приоритет, чемscreenId
.
Например, если необходимо открыть определенный экран редактирования в режиме диалога, действие можно сконфигурировать в XML следующим образом:
<action id="view" type="view">
<properties>
<property name="openMode" value="DIALOG"/>
<property name="screenClass" value="com.company.sales.web.customer.CustomerEdit"/>
</properties>
</action>
В качестве альтернативы, действие можно инжектировать в контроллер экрана и сконфигурировать, используя сеттеры:
@Named("customersTable.view")
private ViewAction customersTableView;
@Subscribe
public void onInit(InitEvent event) {
customersTableView.setOpenMode(OpenMode.DIALOG);
customersTableView.setScreenClass(CustomerEdit.class);
}
Далее рассматриваются параметры, которые можно сконфигурировать только программно в Java. Для генерации корректно аннотированных методов для этих параметров используйте закладку Handlers окна инструментов Component Inspector в Studio.
-
screenOptionsSupplier
- обработчик, возвращающий объектScreenOptions
для передачи в открываемый экран редактирования. Например:@Install(to = "customersTable.view", subject = "screenOptionsSupplier") protected ScreenOptions customersTableViewScreenOptionsSupplier() { return new MapScreenOptions(ParamsMap.of("someParameter", 10)); }
Возвращаемый объект
ScreenOptions
будет доступен вInitEvent
открываемого экрана. -
screenConfigurer
- обработчик, принимающий экран редактирования для его конфигурирования перед открытием. Например:@Install(to = "customersTable.view", subject = "screenConfigurer") protected void customersTableViewScreenConfigurer(Screen editorScreen) { ((CustomerEdit) editorScreen).setSomeParameter(10); }
Конфигуратор экрана вступает в действие, когда экран уже инициализирован, но еще не показан, то есть после
InitEvent
иAfterInitEvent
, и доBeforeShowEvent
. -
afterCommitHandler
- обработчик, вызываемый после коммита редактируемого экземпляра сущности в экране редактирования, если пользователь переключил экран в режим редактирования используя действиеenableEditing
, упомянутое выше. Принимает сохраненный в БД экземпляр сущности. Например:@Install(to = "customersTable.view", subject = "afterCommitHandler") protected void customersTableViewAfterCommitHandler(Customer entity) { System.out.println("Updated " + entity); }
-
afterCloseHandler
- обработчик, вызываемый после закрытия экрана редактирования. ПринимаетAfterCloseEvent
. Например:@Install(to = "customersTable.view", subject = "afterCloseHandler") protected void customersTableViewAfterCloseHandler(AfterCloseEvent event) { if (event.closedWith(StandardOutcome.COMMIT)) { System.out.println("Enabled editing and then committed"); } }
Для того, чтобы произвести какие-либо проверки, или взаимодействовать с пользователем перед выполнением действия, необходимо подписаться на событие ActionPerformedEvent
действия и в нужный момент вызвать метод execute()
. Действие будет вызвано со всеми параметрами, которые были для него заданы. В примере ниже перед выполнением действия отображается диалог подтверждения:
@Named("customersTable.view")
private ViewAction customersTableView;
@Subscribe("customersTable.view")
public void onCustomersTableView(Action.ActionPerformedEvent event) {
dialogs.createOptionDialog()
.withCaption("Please confirm")
.withMessage("Do you really want to view the customer?")
.withActions(
new DialogAction(DialogAction.Type.YES)
.withHandler(e -> customersTableView.execute()), // execute action
new DialogAction(DialogAction.Type.NO)
)
.show();
}
Можно также подписаться на ActionPerformedEvent
, и вместо вызова метода execute()
действия, использовать для открытия экрана редактирования ScreenBuilders
API напрямую. По сути, в этом случае все специфичные параметры действия игнорируются, и действуют только общие параметры: caption, icon, и т.д. Например:
@Inject
private ScreenBuilders screenBuilders;
@Subscribe("customersTable.view")
public void onCustomersTableView(Action.ActionPerformedEvent event) {
CustomerEdit customerEdit = screenBuilders.editor(customersTable)
.withOpenMode(OpenMode.DIALOG)
.withScreenClass(CustomerEdit.class)
.withAfterCloseListener(afterScreenCloseEvent -> {
if (afterScreenCloseEvent.closedWith(StandardOutcome.COMMIT)) {
Customer committedCustomer = (afterScreenCloseEvent.getScreen()).getEditedEntity();
System.out.println("Updated " + committedCustomer);
}
})
.build();
customerEdit.setReadOnly(true);
customerEdit.show();
}