5.5.1.3.4. AbstractEditor
AbstractEditor
− базовый класс контроллеров экранов редактирования, является наследником AbstractWindow.
При создании конкретного класса контроллера рекомендуется параметризовать AbstractEditor
типом редактируемой сущности. При этом методы getItem()
и initNewItem()
будут работать с конкретным типом сущности и прикладному коду не потребуется дополнительных приведений типов. Например:
public class CustomerEdit extends AbstractEditor<Customer> {
@Override
protected void initNewItem(Customer item) {
...
AbstractEditor
определяет следующие собственные методы:
-
getItem()
- возвращает экземпляр редактируемой сущности, установленный в главном источнике данных экрана (т.е. указанном в атрибутеdatasource
корневого элемента XML-дескриптора).Если редактируется не новый экземпляр, то в момент открытия экрана он перезагружается из базы данных с необходимым представлением, указанным для главного источника данных.
Изменения, вносимые в экземпляр, возвращаемый
getItem()
, отражаются на состоянии источника данных, и будут отправлены на Middleware при коммите экрана.WarningСледует иметь в виду, что
getItem()
возвращает значение только после инициализации экрана методомsetItem()
. До этого момента, например, в методахinit()
иinitNewItem()
, данный метод возвращаетnull
.Однако в методе
init()
экземпляр сущности, переданный вopenEditor()
, можно получить из параметров следующим образом:@Override public void init(Map<String, Object> params) { Customer item = WindowParams.ITEM.getEntity(params); // do something }
В метод
initNewItem()
экземпляр передается явно и нужного типа.В обоих случаях полученный экземпляр сущности, если он не новый, будет впоследствии перезагружен, и вносить в него изменения или сохранять в поле для последующего использования не имеет смысла.
-
setItem()
- вызывается фреймворком при открытии экрана методомopenEditor()
для установки редактируемого экземпляра сущности в главном источнике данных. В момент вызова созданы все компоненты и источники данных экрана, и отработал методinit()
контроллера.Для инициализации экрана редактирования вместо переопределения
setItem()
рекомендуется имплементировать специальные шаблонные методыinitNewItem()
иpostInit()
.
-
initNewItem()
- шаблонный метод, вызываемый фреймворком перед установкой редактируемого экземпляра сущности в главном источнике данных.TipМетод
initNewItem()
вызывается только для нового, только что созданного экземпляра сущности. Если редактируется detached экземпляр, метод не вызывается.Данный метод можно имплементировать в контроллере при необходимости инициализации нового экземпляра сущности перед его установкой в источник данных, например:
@Inject private UserSession userSession; @Override protected void initNewItem(Complaint item) { item.setOpenedBy(userSession.getUser()); item.setStatus(ComplaintStatus.OPENED); }
Более сложный пример использования
initNewItem()
приведен в разделе рецептов разработки.
-
postInit()
- шаблонный метод, вызываемый фреймворком сразу после установки редактируемого экземпляра сущности в главном источнике данных. Во время выполнения данного метода можно вызыватьgetItem()
, который будет возвращать новый или перезагруженный при инициализации экрана экземпляр сущности.Данный метод можно имплементировать в контроллере для окончательной инициализации экрана, например:
@Inject private EntityStates entityStates; @Inject protected EntityDiffViewer diffFrame; @Override protected void postInit() { if (!entityStates.isNew(getItem())) { diffFrame.loadVersions(getItem()); } }
-
commit()
- валидировать экран и отправить изменения через DataSupplier на Middleware.Если используется вариант метода с параметром
validate = false
, то валидация перед коммитом не производится.Данный метод не рекомендуется переопределять, лучше использовать специальные шаблонные методы
postValidate()
,preCommit()
иpostCommit()
.
-
commitAndClose()
- валидировать экран, отправить изменения на Middleware и закрыть экран. В методpreClose()
и зарегистрированным слушателямCloseListener
будет передано значение константыWindow.COMMIT_ACTION_ID
.Данный метод не рекомендуется переопределять, лучше использовать специальные шаблонные методы
postValidate()
,preCommit()
иpostCommit()
.
-
preCommit()
- шаблонный метод, вызываемый фреймворком в процессе коммита изменений, после того как валидация завершена успешно и перед отправкой данных на Middleware.Данный метод можно имплементировать в контроллере. Если метод возвращает
false
, процесс коммита (и закрытия экрана, если был вызванcommitAndClose()
), прерывается. Например:@Override protected boolean preCommit() { if (somethingWentWrong) { showNotification("Something went wrong", NotificationType.WARNING); return false; } return true; }
-
postCommit()
- шаблонный метод, вызываемый фреймворком на финальной стадии коммита изменений. Параметры метода:-
committed
- установлен вtrue
, если в экране действительно были изменения, и они отправлены на Middleware; -
close
- установлен вtrue
, если экран после коммита будет закрыт.Реализация метода по умолчанию, если экран не закрывается, отображает сообщение об успешном коммите изменений и вызывает метод
postInit()
.Данный метод можно переопределить в контроллере для выполнения некоторых действий после успешного коммита, например:
@Inject private Datasource<Driver> driverDs; @Inject private EntitySnapshotService entitySnapshotService; @Override protected boolean postCommit(boolean committed, boolean close) { if (committed) { entitySnapshotService.createSnapshot(driverDs.getItem(), driverDs.getView()); } return super.postCommit(committed, close); }
-
Далее приведены диаграммы последовательностей инициализации и различных вариантов коммита экрана редактирования.
- API
-
commit() - commitAndClose() - getItem() - initNewItem() - postCommit() - postInit() - preCommit() - setItem()