3.6.1.3.4. AbstractEditor
|
Это устаревший API. Новый API, доступный начиная с v.7.0, описан в разделе Контроллер экрана. |
AbstractEditor − базовый класс контроллеров экранов редактирования, является наследником AbstractWindow.
При создании конкретного класса контроллера рекомендуется параметризовать AbstractEditor типом редактируемой сущности. При этом методы getItem() и initNewItem() будут работать с конкретным типом сущности и прикладному коду не потребуется дополнительных приведений типов. Например:
public class CustomerEdit extends AbstractEditor<Customer> {
@Override
protected void initNewItem(Customer item) {
...
AbstractEditor определяет следующие собственные методы:
-
getItem()- возвращает экземпляр редактируемой сущности, установленный в главном источнике данных экрана (т.е. указанном в атрибутеdatasourceкорневого элемента XML-дескриптора).Если редактируется не новый экземпляр, то в момент открытия экрана он перезагружается из базы данных с необходимым представлением, указанным для главного источника данных.
Изменения, вносимые в экземпляр, возвращаемый
getItem(), отражаются на состоянии источника данных, и будут отправлены на Middleware при коммите экрана.Следует иметь в виду, что
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()- шаблонный метод, вызываемый фреймворком перед установкой редактируемого экземпляра сущности в главном источнике данных.Метод
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) { notifications.create() .withCaption("Something went wrong") .withType(Notifications.NotificationType.WARNING) .show(); 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()