Настройка диалога LOV:
Вы можете легко настроить диалог LOV, создав свой собственный класс действия LOV, который установлен рядом с эталонными полей.
- Добавление нового действия в диалоговом окне (создавание действие):
public class LovActionWithCreate<E, F, G> extends LovAction<E, F, G> {
private IDisplayableAction createAction;
@Override
protected void feedContextWithDialog(IReferencePropertyDescriptor<IComponent> erqDescriptor,
IQueryComponent queryComponent, IView<E> lovView, IActionHandler actionHandler,
Map<String, Object> context) {
super.feedContextWithDialog(erqDescriptor, queryComponent, lovView, actionHandler, context);
List<IDisplayableAction> defaultLovDialogActions = (List<IDisplayableAction>) context.get(
ModalDialogAction.DIALOG_ACTIONS);
defaultLovDialogActions.add(1, getCreateAction());
}
/**
* Gets create action.
*
* @return the create action
*/
protected IDisplayableAction getCreateAction() {
return createAction;
}
/**
* Sets create action.
*
* @param createAction
* the create action
*/
public void setCreateAction(IDisplayableAction createAction) {
this.createAction = createAction;
}
}
Ключевым моментом является то, чтобы переопределить метод feedContextWithDialog
для того, чтобы установить новое действие в диалоговом окне.
Следующий шаг - установить новое действие LOV. Вы можете сделать это глобально для всего приложения или на опорной точки зрения:
- заменить действие LOV глобально это всего лишь вопрос того, чтобы объявить акцию под названием
'lovAction'
в приложение frontend.groovy
, а именно:
action('lovAction', parent: 'lovActionBase', class:'test.LovActionWithCreate',
custom: [createAction_ref:'theCreateAction']
)
- заменив действие LOV на определенном опорное поле в форме может быть сделан с помощью
referencePropertyView
(в form
или в table
) и его свойство «lovAction», например,:
action('lovActionWithCreate', parent: 'lovActionBase', class:'test.LovActionWithCreate',
custom: [createAction_ref:'theCreateAction']
)
form('ACertainForm'){
fields {
...
referencePropertyView name:'country', lovAction:'lovActionWithCreate'
...
}
}
Создание сущности в диалоге LOV:
На следующем шаге мы создадим действие, которое будет нести ответственность за открытие дополнительного диалога для того, чтобы создать новый объект, сохраняйте его и, в случае успеха, добавьте его в представление результата LOV. Это немного сложнее, но не так много.
- Прежде всего, мы должны открыть новое диалоговое окно.
Для этого мы наследуем встроенный EditComponentAction
. Цель этого действия - отредактировать модель в модальном диалоге. Единственная трудность здесь заключается в том, что наша модель известна только во время работы. Нет проблем, хотя мы будем использовать динамический характер Jspresso.
public class CreateEntityFromLOVAction<E, F, G> extends EditComponentAction<E,F,G> {
@Override
protected Object getComponentToEdit(Map<String, Object> context) {
IEntityFactory entityFactory = getBackendController(context).getEntityFactory();
IQueryComponent lovQueryComponent = (IQueryComponent) context.get(IQueryComponent.QUERY_COMPONENT);
Class<IEntity> entityToCreateContract = lovQueryComponent.getQueryContract();
IEntity entityInstance = entityFactory.createEntityInstance(entityToCreateContract);
setActionParameter(Arrays.asList(entityInstance), context);
return entityInstance;
}
@Override
protected IViewDescriptor getViewDescriptor(Map<String, Object> context) {
IEntityFactory entityFactory = getBackendController(context).getEntityFactory();
IQueryComponent lovQueryComponent = (IQueryComponent) context.get(IQueryComponent.QUERY_COMPONENT);
Class<IEntity> entityToCreateContract = lovQueryComponent.getQueryContract();
IComponentDescriptor<?> entityToCreateDescriptor = entityFactory.getComponentDescriptor(entityToCreateContract);
BasicComponentViewDescriptor formViewDescriptor = new BasicComponentViewDescriptor();
formViewDescriptor.setModelDescriptor(entityToCreateDescriptor);
return formViewDescriptor;
}
}
Если вы посмотрите на код выше, наше новое действие заботится о следующих:
- Получить тип объекта, чтобы создать из контекста. Для этого мы просто изучаем компонент запроса, который является моделью диалога LOV.
- Создайте экземпляр сущности и установите его как параметр действия в контексте, чтобы цепочка продолжала работать над ним (сохранить, закрыть диалог).
- Создайте форму для отображения в диалоговом окне создания.
Точки 1 и 2 обрабатываются методом getComponentToEdit
и пунктом 3 методом getViewDescriptor
.
- Затем, когда пользователь нажимает
Ok
, мы должны сохранить объект, добавить его в список результатов LOV и закрыть диалоговое окно создания.
Для этого мы создадим новое действие и подключим его к saveAction
и closeDialogAction
встроенным действиям.
public class CreateEntityFromLOVPersistAction<E, F, G> extends FrontendAction<E,F,G> {
@Override
public boolean execute(IActionHandler actionHandler, Map<String, Object> context) {
if (super.execute(actionHandler, context)) {
IQueryComponent lovQueryComponent = (IQueryComponent) context.get(IQueryComponent.QUERY_COMPONENT);
List<IEntity> createdEntityInstance = getActionParameter(context);
lovQueryComponent.setQueriedComponents(createdEntityInstance);
return true;
}
return false;
}
}
- И последняя проводка в SJS
frontend.groovy
:
action('createEntityFromLovOkAction', parent: 'okDialogFrontAction',
class:'test.CreateEntityFromLOVPersistAction',
wrapped: 'saveBackAction', next: 'closeDialogAction')
action('createEntityFromLovAction', parent: 'editComponentAction',
class: 'test.CreateEntityFromLOVAction',
name:'add.name', custom: [
okAction_ref: 'createEntityFromLovOkAction'
]
)
action('lovAction', parent: 'lovActionBase',
class:'test.LovActionWithCreate',
custom: [createAction_ref:'createEntityFromLovAction']
)
Длинный ответ менее чем 100 строк кода, но теперь у вас есть полностью общие действия LOV, где пользователь может создайте любые отсутствующие основные данные, не покидая его текущего экрана.
Предустановка некоторые данные в LOV фильтра в зависимости от контекста пользователя:
Для этого, мы обычно используем отображениеинициализации, которая позволяет установить некоторые ограничения (либо статические или динамические) на эталонном собственности когда он запрашивается в LOV.Например, давайте рассмотрим следующий случай использования:
- У вас есть 2 сущностей,
Contract
и Tariff
, которые связаны друг с другом через отношения 1-N, т.е. Contract
связан с 1 Tariff
.
Contract
и Tariff
оба имеют country
свойство и Tariff
может быть назначен Contract
тогда и только тогда, когда они принадлежат к одной и той же стране.
Tarrif
имеет свойство status
и может использоваться только в Contract
, если его status
является ACTIVE
.
Вы можете просто применять эти правила в LOV, установив отображение инициализации на опорном собственности следующим образом:
Entity('Contract', ...) {
...
reference 'tariff', ref: 'Tariff',
initializationMapping: [
'country': 'country',
'status': 'ACTIVE'
]
...
}
Думая об этом, такое поведение может очень хорошо найти его путь к структуре, поэтому, пожалуйста, не стесняйтесь использовать запрос расширения в Jspresso GitHub.
Hi Vincent, Всего комментариев: Я добавил это поведение в свое приложение, как вы изящно объяснили в своем ответе. Оно работало завораживающе. Спасибо. – Weggyboy
Стандартное действие LOV было улучшено, чтобы включить эту функциональность в предстоящий Jspresso 4.3. См. [Этот вопрос Github] (https://github.com/jspresso/jspresso-ce/issues/41) –