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 アクションをインストールすることです。アプリケーション全体または参照ビューごとにグローバルに実行できます。
'lovAction'
LOV アクションをグローバルに置き換えるには、アプリケーションに名前付きのアクションを宣言するだけです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 の関係でリンクされています。つまり、 aContract
は 1 にリンクされていTariff
ます。
Contract
Tariff
両方にcountry
プロパティがあり、同じ国に属している場合にのみ、 をTariff
に割り当てることができます。Contract
Tarrif
にはstatus
プロパティがあり、 isのContract
場合にのみ使用できます。status
ACTIVE
次の方法で参照プロパティに初期化マッピングを設定することで、LOV でこれらのルールを適用できます。
Entity('Contract', ...) {
...
reference 'tariff', ref: 'Tariff',
initializationMapping: [
'country': 'country',
'status': 'ACTIVE'
]
...
}
考えてみれば、この種の動作はフレームワークにまで行き着く可能性が非常に高いので、お気軽にJspresso GitHubで拡張リクエストを送信してください。