##はじめに
CDS + BOPFでFioriアプリケーションを作るシリーズの続きです。
今回はActionを使って選択したデータをコピーする機能を追加します。
前回の記事
【BOPF】Determination, Validationの実装
##今回のゴール
- UIにコピーボタンが表示されるようにする
- コピーボタンを押すと、選択した行のデータがコピーされる
##ステップ
- BOPFにActionを追加
- UIアノテーションを追加
##BOPFにActionを追加
###Actionを登録する
前回と同じ要領で、BOPFのルートノードにアクションを追加します。
ここで有効化します。
いまさらですが、機能ごとに別のクラスになるので、同じBOPFに属するクラスを識別できる命名にしたほうがいいですね。
###生成されたクラスの構造
/BOBF/CL_LIB_A_SUPERCL_SIMPLEというクラスを継承しています。
/BOBF/IF_FRW_ACTIONというインターフェースが実装されています。
Determination, Validationと同様にメソッドは3つあり、EXECUTEというメソッドを再定義するようになっています。
###Actionロジックを実装する
今回はコピー機能を作るので、以下のステップで実装します。
- 処理対象のデータ(選択された行)を取得する
- 選択された行をコピーし、新しいデータを登録する
####処理対象のデータ(選択された行)を取得する
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を設定しました。
2020/12/8更新:以下のように一つの項目に複数のlineItemアノテーションをつけることができます。こうすると、その項目は一覧にも表示されます。
@UI.lineItem: [
{ position: 10 },
{ position: 10, type:#FOR_ACTION, dataAction: 'BOPF:COPY', label:'Copy'}]
first_name;
##実行結果
Copyボタンを押すと、
何も起きません。
Goボタンを押すとコピーされた行が表示されました。
アクション後のリフレッシュや、メッセージを出すなどの機能については研究が必要そうです。とりあえず、アクションが動作していることは確認できました。