1

私の現在のプロジェクトでは、参照オブジェクトを検索するときに新しいオブジェクトを作成できるようにしたいと考えています。これは、アプリケーションのいくつかの場所で発生します。

たとえば、City エンティティと Country エンティティがあるとします。City エンティティには、Country エンティティへの必須の参照があります。

私のユースケースでは、新しい都市を作成したいと考えています。これを行うとき、国を新しい都市に割り当てる必要があります。検索アイコンをクリックすると、存在するすべての国を含む選択ダイアログが表示されます。しかし、必要な国がない場合は、操作を中止し、国のリストに戻って、新しい都市に割り当てたい新しい国を作成する必要があります。

  1. すべての国を含む選択ダイアログからその新しい国を作成することは可能でしょうか?
  2. 可能であれば、その国は作成直後にリストに追加されていますか?
  3. 国のリストの範囲を定義することは可能でしょうか? たとえば、ユーザーがヨーロッパにいる場合、ヨーロッパの国のみを表示します。

これは、フレームワークから多くのことを要求することになると想像できました。しかし、私はただ試してみるだけで、おそらく新しい機能のアイデアも提供しています。

4

1 に答える 1

3

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;
  }
}

上記のコードを見ると、新しいアクションは次のことを処理します。

  1. コンテキストから作成するエンティティのタイプを取得します。このために、LOV ダイアログのモデルであるクエリ コンポーネントを調べています。
  2. エンティティ インスタンスを作成し、それをチェーンのコンテキストでアクション パラメータとして設定して、処理を続行します (保存、ダイアログを閉じます)。
  3. 作成ダイアログに表示するフォームを作成します。

ポイント 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ます。
  • ContractTariff両方にcountryプロパティがあり、同じ国に属している場合にのみ、 をTariffに割り当てることができます。Contract
  • Tarrifにはstatusプロパティがあり、 isのContract場合にのみ使用できます。statusACTIVE

次の方法で参照プロパティに初期化マッピングを設定することで、LOV でこれらのルールを適用できます。

Entity('Contract', ...) {
  ...
  reference 'tariff', ref: 'Tariff',
       initializationMapping: [
            'country': 'country',
            'status': 'ACTIVE'
       ]
  ...
}

考えてみれば、この種の動作はフレームワークにまで行き着く可能性が非常に高いので、お気軽にJspresso GitHubで拡張リクエストを送信してください。

于 2015-08-28T13:31:02.057 に答える