Фасет drafts
Фасет drafts сохраняет несохраненные изменения экрана в виде черновика и предлагает восстановить черновик, когда пользователь снова открывает экран. Общее описание см. в разделе Как это работает.
Добавление фасета
Объявите пространство имен дополнения в дескрипторе экрана:
<view xmlns="http://jmix.io/schema/flowui/view"
xmlns:uirec="http://jmix.io/schema/uirecovery/ui"
title="msg://OrderDetailView.title"
focusComponent="form">
Затем добавьте элемент uirec:drafts в элемент facets:
<facets>
<dataLoadCoordinator auto="true"/>
<uirec:drafts id="draftsFacet"/>
</facets>
В Jmix Studio фасет можно добавить из раздела Facets палитры компонентов.
Фасет работает в любом экране, у которого есть DataContext, и сохраняет изменения, зарегистрированные в нем. В экране деталей черновик относится к редактируемой записи. В других экранах, например в экране списка с редактируемой таблицей данных, у экрана один черновик.
|
Вы можете просматривать и редактировать атрибуты фасета в Jmix Studio используя панель испектора Jmix UI. |
Атрибуты
Поведение фасета в конкретном экране можно изменить с помощью следующих атрибутов:
<facets>
<dataLoadCoordinator auto="true"/>
<uirec:drafts id="draftsFacet" restoreMode="AUTO" minSaveInterval="10s"/>
</facets>
minSaveInterval-
Минимальное время между двумя сохранениями черновика экрана, например
5sили1m. Изменения, сделанные в течение этого времени, сохраняются по окончании интервала. Значение по умолчанию задается свойством jmix.uirecovery.drafts.default-min-save-interval.
restoreMode-
Способ восстановления черновика при открытии экрана:
ASKилиAUTO. См. Режимы восстановления. Значение по умолчанию задается свойством jmix.uirecovery.drafts.default-restore-mode.
Сохранение и удаление черновиков
Фасет сохраняет черновик после того, как пользователь изменил данные в экране, но не чаще, чем позволяет minSaveInterval. Когда экран отсоединяется, например потому что пользователь закрыл вкладку браузера, фасет сразу сохраняет оставшиеся изменения.
Фасет удаляет черновик, когда:
-
Пользователь сохраняет изменения.
-
Пользователь закрывает экран и подтверждает, что изменения нужно отменить.
Если сохранить черновик не удалось, ошибка записывается в лог, и экран продолжает работать.
Сохранение вводимых значений
По умолчанию текстовое поле отправляет значение на сервер, когда поле теряет фокус или пользователь нажимает Enter. До этого момента введенное значение отсутствует в модели данных и не может быть сохранено в черновике. Если пользователь вводит длинный текст в одно поле, при сбое весь этот текст может быть потерян.
Чтобы отправлять значение во время ввода, установите для атрибута поля valueChangeMode значение LAZY или TIMEOUT:
<textArea id="commentField" property="comment" height="9.5em"
valueChangeMode="LAZY" valueChangeTimeout="1000"/>
В этом примере текстовая область отправляет значение, когда пользователь прекращает ввод на одну секунду. Затем значение сохраняется в следующем черновике. Каждое отправленное значение — это запрос к серверу, поэтому используйте эту настройку для полей, в которые пользователи вводят много текста.
Режимы восстановления
Когда экран открывается и для него найден черновик, фасет восстанавливает черновик в соответствии с режимом восстановления.
ASK
Это режим по умолчанию. Фасет показывает диалог с датой черновика:
-
Restore переносит изменения из черновика в экран. Изменения не сохраняются в базу данных, пока пользователь не сохранит экран.
-
Discard удаляет черновик.
-
Not now закрывает диалог и сохраняет черновик. Диалог будет показан снова, когда пользователь в следующий раз откроет экран.
Если запись была изменена другим пользователем после сохранения черновика, диалог предупреждает, что восстановление черновика перезапишет эти изменения:
Предупреждение показывается для сущностей с оптимистичной блокировкой, то есть сущностей с атрибутом версии.
Что восстанавливается
Фасет восстанавливает только те атрибуты, которые изменил пользователь. Остальные атрибуты сохраняют текущие значения.
Фасет пропускает части черновика, которые больше нельзя применить, и восстанавливает остальное. Например, он пропускает:
-
Атрибут, который был удален из сущности в новой версии приложения.
-
Запись, которая была удалена после сохранения черновика.
Если черновик вообще не удается прочитать, фасет удаляет его, и экран открывается без восстановления. Пользователь не получает уведомления. Подробности записываются в лог.
Собственная логика восстановления
Чтобы в коде решать, восстанавливать ли черновик и как, задайте делегат восстановления. Фасет вызывает его перед стандартным восстановлением. Делегат получает объект DraftRestoreContext с найденным черновиком и экраном. Если делегат вызывает preventRestore(), фасет не восстанавливает черновик и не показывает диалог.
В следующем примере экран не предлагает черновики старше одного дня и удаляет их:
@ViewComponent
private DraftsFacet draftsFacet;
@Autowired
private TimeSource timeSource;
@Install(to = "draftsFacet", subject = "restoreDelegate")
private void draftsFacetRestoreDelegate(final DraftRestoreContext context) {
OffsetDateTime draftDate = context.getDraft().getCreatedDate();
OffsetDateTime minDate = timeSource.now().toOffsetDateTime().minus(Duration.ofDays(1));
if (draftDate.isBefore(minDate)) {
context.preventRestore(); (1)
draftsFacet.deleteDrafts(); (2)
}
}
| 1 | Фасет не восстанавливает черновик и не показывает диалог. |
| 2 | Удаляет черновик текущего экрана и записи. |
DraftRestoredEvent
Фасет отправляет DraftRestoredEvent после восстановления черновика. Событие отправляется в обоих режимах восстановления. В этот момент восстановленные значения уже находятся в экране, поэтому можно обновить UI или проверить данные. Изменения, сделанные в обработчике события, сохраняются в следующем черновике.
Метод события getDraft() возвращает восстановленный черновик, а getRestoredEntities() — экземпляры сущностей, которые были изменены при восстановлении.
Событие не отправляется, если пользователь отменил черновик или отложил решение, если делегат восстановления запретил восстановление или если из черновика ничего не удалось восстановить.
В следующем примере экран проверяет восстановленные значения и показывает ошибки валидации:
@ViewComponent
private JmixFormLayout form;
@Autowired
private ViewValidation viewValidation;
@Subscribe("draftsFacet")
public void onDraftRestored(final DraftsFacet.DraftRestoredEvent event) {
ValidationErrors errors = viewValidation.validateUiComponents(form);
if (!errors.isEmpty()) {
viewValidation.showValidationErrors(errors);
}
}
Методы
Интерфейс DraftsFacet имеет следующие методы:
-
saveDraftNow()сохраняет черновик немедленно, не дожидаясь окончания minSaveInterval. -
deleteDrafts()удаляет черновик текущего экрана и записи. -
setMinSaveInterval()иsetRestoreMode()изменяют значения атрибутов. -
setRestoreDelegate()задает делегат восстановления. -
addDraftRestoredListener()добавляет слушатель DraftRestoredEvent.