OutSystems 10と11でのBlockから親画面への通知方法の変化

この記事は、バージョン10を使用するメンバーへの11での新機能紹介のために書いています。
OutSystemsバージョン10までは、(Web)Blockから親画面へ情報を伝えるためには、Text型のみ渡せるNotifyを使う方法しかありませんでした。
11では、これにEventという方法が追加されました。EventにはText型以外の情報を渡せるため、強い型付けが使用できることになります。

なお、Mobileでは10の頃から使えました。

# 実装方法の変更点
## 変更点の概要
上が、OutSystemsバージョン10時点でWeb BlockからScreenに情報を通知するNotifyを使った実装イメージ。
下が、バージョン11で使えるようになったEventを使った実装イメージです。
![qEvent1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332987/178940bb-f9e6-d925-5b66-e9134e6e46ee.png)

イメージは複雑な構造のデータを値として渡すケースを前提としています。

バージョン10(Notify利用パターン)
1. データはStructureで定義します。
2. Web BlockからScreenにデータを渡すときはNotify(又はそれに類する)Actionを使います。パラメータはText型であるため、それに合わないパラメータはJSON SerializeなどでTextに変換
3. Screenに配置したBlockが内部でNotifyを使っていると、ScreenのプロパティにOn Notifyが表示されます。ここにScreen Actionを指定してデータを取り出す仕組み
4. Screen Actionでは、NotifyGetMessageでText型のデータを取り出す。そして、JSON Deserializeなどで本来欲しかった型に変換して利用する

バージョン11(Event利用パターン)
1. データをStructureで定義するのは10のときと同じ。11ではデータをEventに包んで渡します。そこで、BlockにEvent（Input ParameterにStructureを型とした変数を設定）を追加しておきます
2. 11からはBlockのScreen ActionのFlow内で「Trigger Event」というツールが使えます。そのEventプロパティに1.で定義したEventを指定し、（あれば）Input Parameterに引き渡したいデータを指定
3. Eventを定義したBlockを配置したScreenでは、Eventsの下に定義されたEventが列挙され、イベントに対するハンドラとなるScreen Actionを指定します
4. ハンドラはInput ParameterにEventに対して渡した値をそのまま受け取れます。つまりNotifyと違って本来の値に戻す操作が不要

## NotifyからEventにする利点
以下のような点が良いと思います。

- 型が明確に定義される
    - 余分なText型との相互の変換が不要
    - 開発／保守担当者はモデルを見て正確に定義を把握できる
- 複数のイベントを持つBlockで、発生するイベントごとに別のScreen Actionを明確に指定できる（Notifyだと通知された値を見て自分で分岐しないといけない）

## サンプル
ForgeコンポーネントFullCalendar 2を使って実装方法の変化を見てみましょう。

バージョン10のサンプル：OutSystemsバージョン10向けに作られたv4.0.1
バージョン11のサンプル：OutSystemsバージョン11向けに作られたv4.0.3

https://www.outsystems.com/forge/component-versions/966

## Forgeコンポーネントの別バージョンを比較する方法
実際にService Studioで確認して見るときは、上記URLから対応するバージョンのファイルをダウンロードします。
これは.oapという形式のファイルになっていますが、Service Studioがインストールされている環境でダブルクリックするとインストールが始まってしまいます。
そこで、zipファイルとして展開すると、中に.omlファイルが含まれています。これをService Studio上で比較してみてください。

# イベント
## 参考資料
[公式ドキュメント](https://success.outsystems.com/Documentation/11/Developing_an_Application/Design_UI/Reuse_UI/Use_Events_to_Propagate_Changes_From_a_Block_to_the_Parent)
[Reactive Web App用のBlock Events（字幕あり）動画](https://www.outsystems.com/learn/lesson/1902/block-events)

## 実装手順
Block1つを作成し、Screenに配置して発生したイベントを処理するまでの手順は以下の通り。
BlockとScreenは事前に作成済みとします。

1. (Block)Blockを右クリックし、「Add Event」を選択
![qEvent2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332987/49fd0c1f-837d-9b83-e454-a45427d7c59c.png)
2. (Block)作成したEventを右クリックし、「Add Input Parameter」を選択
![qEvent3.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332987/032fc9b7-5397-4076-d309-0999f480ee87.png)

　追加したParameterのData TypeをScreenに引き渡したいものに変更しておきます
3. (Block)適当なScreen Action中に「Trigger Event」を配置。1-2で作成したEventを指定
![qEvent4.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332987/93ef2434-b0e1-a4fa-47a8-5b46a02b10af.png)
Screen Action中で編集したLocal Variableを、Eventのパラメータにしてあります。
4. (Screen)作成したBlockを配置してみると、下のように定義したEventに対するHandlerを指定するようになっています。
![qEvent5.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332987/83ee4358-d4b1-a36f-ea70-bc249c7fd296.png)
5. (Screen)4.で(New Screen Action)を選ぶと作成されるScreen ActionにはEventに渡したInput ParameterがそのままScreen ActionのInput Parameterとして渡される。この後は普通のScreen Actionとして処理できる

## その他
* EventのIs MandatoryプロパティをYesにしたイベントは、必ず配置先のScreenで処理しないといけなくなる（ハンドラ指定が強制される）
* デバッグして追いかけてみると、イベント発生後の制御は、Screenでハンドラが動作した後、再びBlockのScreen Actionに戻ってくる
* Traditional WebのBlockにはないが、「On Parameters Changed」というイベントがある。配置した先のScreenでBlockに設定したInput Parameterの値が変わるとこのイベントが発生する