Help us understand the problem. What is going on with this article?

【BOPF】Actionの実装

はじめに

CDS + BOPFでFioriアプリケーションを作るシリーズの続きです。
今回はActionを使って選択したデータをコピーする機能を追加します。

前回の記事
【BOPF】Determination, Validationの実装

今回のゴール

  • UIにコピーボタンが表示されるようにする
  • コピーボタンを押すと、選択した行のデータがコピーされる

ステップ

  1. BOPFにActionを追加
  2. UIアノテーションを追加

BOPFにActionを追加

Actionを登録する

前回と同じ要領で、BOPFのルートノードにアクションを追加します。
image.png
image.png
image.png
ここで有効化します。
image.png

いまさらですが、機能ごとに別のクラスになるので、同じBOPFに属するクラスを識別できる命名にしたほうがいいですね。

生成されたクラスの構造

/BOBF/CL_LIB_A_SUPERCL_SIMPLEというクラスを継承しています。
image.png
/BOBF/IF_FRW_ACTIONというインターフェースが実装されています。
image.png
Determination, Validationと同様にメソッドは3つあり、EXECUTEというメソッドを再定義するようになっています。
image.png

Actionロジックを実装する

今回はコピー機能を作るので、以下のステップで実装します。
1. 処理対象のデータ(選択された行)を取得する
2. 選択された行をコピーし、新しいデータを登録する

処理対象のデータ(選択された行)を取得する

Determinationと同様の方法で処理対象のデータを取得します。

    DATA: lt_data TYPE ztmob58_c_students.

    io_read->retrieve(
      EXPORTING
        iv_node                 = is_ctx-node_key        " Node Name
        it_key                  = it_key                 " Key Table
      IMPORTING
        et_data                 = lt_data                " Data Return Structure
    ).

選択された行をコピーし、新しいデータを登録する

まず、2つの変数を追加します。

    DATA: lt_data TYPE ztmob58_c_students,
          ls_copy TYPE zsmob58_c_students,
          lo_copy TYPE REF TO data.

処理対象行をコピーし、createメソッドに渡します。

    LOOP AT lt_data INTO DATA(lw_data).
      "行をコピー
      ls_copy = VALUE #(
                         first_name = | { lw_data-first_name } _copy |  "コピーしたことがわかるように、末尾に_copyとつける
                         last_name  = lw_data-last_name
                         birthday   = lw_data-birthday
                         region     = lw_data-region
                         city       = lw_data-city
                         street     = lw_data-street
                         location   = lw_data-location
                        ).

      "データオブジェクトを登録      
      CREATE DATA lo_copy TYPE zsmob58_c_students.
      "データオブジェクトにコピーした行を参照させる
      ASSIGN lo_copy->* TO FIELD-SYMBOL(<fs_copy>).
      IF <fs_copy> IS ASSIGNED.
        <fs_copy> = ls_copy.
      ENDIF.

      io_modify->create(
        EXPORTING
          iv_node            = is_ctx-node_key   " Node to Create
          is_data            = lo_copy           " Data
        IMPORTING
          ev_key             = DATA(lv_key)
      ).

    ENDLOOP.

データオブジェクトやフィールドシンボルが出てきて複雑ですが、次のようなことをしています。
①処理対象行をコピーして、構造ls_copyに格納
②データオブジェクトを登録(createメソッドの引数is_dataがオブジェクト型なので、オブジェクト型を渡すため)
③データオブジェクトにls_copyの内容を参照させる(フィールドシンボルを経由して)

参考にしたのは以下の記事です。
https://eprs.online/2019/04/06/e2e-app-bopf-development/#action

UIアノテーションを追加

画面にCOPYボタンを表示させるために、以下のUIアノテーションを追加します。
@UI.lineItem: [{type:#FOR_ACTION, dataAction: 'BOPF:<ACTIONの名称>', label:'ボタンのテキスト'}]

Metadata Extensionは全体で以下のようになります。

@Metadata.layer: #CORE
annotate view ZMOB58_C_STUDENTS
    with 
{
    @UI.selectionField: [{position: 10 }]
    @UI.lineItem: [{position: 10 }]
    @UI.identification: [{position: 10, label: 'First Name'}]
    first_name; 
    @UI.selectionField: [{position: 20 }]
    @UI.lineItem: [{position: 20 }]
    @UI.identification: [{position: 20, label: 'Last Name'}]
    last_name; 
    @UI.lineItem: [{position: 30 }]
    @UI.identification: [{position: 30, label: 'Birthday'}]
    birthday; 
    @UI.selectionField: [{position: 30 }]
    @UI.lineItem: [{position: 40}]
    @UI.identification: [{position: 40, label: 'Region'}]
    region; 
    @UI.lineItem: [{position: 50, type:#FOR_ACTION, dataAction: 'BOPF:COPY', label:'Copy'}]
    @UI.identification: [{position: 50, label: 'City'}]
    city; 
    @UI.identification: [{position: 60, label: 'Street'}]
    street; 
    @UI.identification: [{position: 70, label: 'Location'}]
    location;
}

問題

今回、cityという項目に対してactionを追加しましたが、どの項目につけても動作は変わりません。(行に対するアクションなので)
ただし、actionを付与した項目は一覧上に表示されなくなる、という挙動をします。解決方法については調査できていません。
暫定策として、表示されなくても困らない項目にactionを設定しました。

実行結果

Copyボタンを押すと、
image.png
何も起きません。
image.png
Goボタンを押すとコピーされた行が表示されました。
image.png

アクション後のリフレッシュや、メッセージを出すなどの機能については研究が必要そうです。とりあえず、アクションが動作していることは確認できました。

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away