画面とブロックのライフサイクルイベント
OutSystemsのモバイルアプリでは、画面とブロックは一連のステージで構成されるライフサイクルに従います。ステージには、アプリを開いてデフォルト画面を表示するとき、他の画面に移動するとき、画面やブロックのデータを変更するとき、などがあります。
画面またはブロックのデータは、以下のとおりです。
- 入力パラメータ
- 変数
- Aggregateとデータアクション
- 検証メッセージ
モバイルアプリの実装中、開発者は一連のイベントハンドラアクションを使用してこれらのステージに対する処理を行います。これらのイベントハンドラによって、開発者は、画面およびブロックのライフサイクルが見えるようになり、特定のイベントが発生したときのロジックを実装できるようになります。
イベントハンドラは、画面とブロックのプロパティエディタの[Events]セクションで参照・定義できます。あるいはデータの取り出しが完了したときにトリガーされたイベントハンドラの場合は、Aggregateまたはデータアクションのプロパティエディタで参照・定義できます。
ライフサイクルの各ステージ
アプリケーションを開くとき
アプリケーションを開くと、画面がロードされます(他の画面から移動してきたときも同様です)。このケースでは、アプリに設定されたスプラッシュ画面が表示された後にデフォルト画面に移動します。
スプラッシュ画面を表示している間、アプリケーションはユーザーロールを画面へのアクセス権限を持つロールと照合します(画面のプロパティに定義されています)。この検証の後、初期化イベントが発生し、それぞれのイベントハンドラアクションであるOn Initializeがトリガーされます。このイベントが発生した時点ではデフォルト画面のDOMは完全にはロードされていないため、(デフォルトデータの一部の初期化などの)DOMを必要としないすべてのロジックをこのイベントハンドラを使用して実装できます。
On Initializeイベントハンドラが終了すると、デフォルト画面のAggregateおよびデータアクションが同時にデータの取り出しを開始します(上記の画像に示されたGetContactsおよびGetProfileImages)。画面のDOMがロードされ、ReadyおよびRenderイベントハンドラが実行されます。これらの2つのイベントの違いは、Readyイベントは画面を開くときにのみ発生するのに対して、Renderイベントはそれに加えて画面のデータ(入力パラメータ、変数、Aggregateおよびデータアクション、または検証メッセージなど)が変更されたときにも必ず発生する点です。ロードされたDOMに対する処理では、両方のイベントハンドラを使用できます。画面のデータはまだ取り出されていない可能性があるため、そのデータにアクセスすることは避けてください。
Aggregateおよびデータアクションからのデータが取り出される前でも、静的リソースを使用して画面が表示されています。この状況を避けるには、オフライン優先の実装アプローチを採用します。
画面のAggregateおよびデータアクションがデータの取り出しを完了したら、これらのデータソースと結び付けられているウィジェットが、取り出されたデータで自動的に更新されます。各AggregateおよびデータアクションのAfter Fetchイベントハンドラが実行され、それに続いてRenderイベントが実行されます(画面のデータが変更されたため)。それぞれのAfter Fetchイベントに対して、アプリケーションがRenderイベントを実行します。
画面間を移動するとき
ある画面から別の画面に移動することは、アプリケーションの非常に一般的なパターンです。これは通常、画面上のボタンまたはリストアイテムをクリックするなどのユーザーインタラクションによってトリガーされます。OutSystemsでは、画面間を移動するということは、新しい画面がロードされ、前の画面が削除されることを意味します。
画面の移動が始まると、移動先画面のDOMのロードがただちに開始されます。つまり、削除される画面と移動先画面のDOMが同時に存在することになります。古い画面のDOMが削除されるのは、移動先画面のRenderイベントの後になります。これにより、画面がすばやく滑らかに遷移し、移動先画面をロードしている段階がユーザーには表示されません。
実行する最初のイベントハンドラは、On Initializeです。アプリケーションは移動先画面のDOMのロードを継続し、アプリケーションを開くときについて説明したセクションのとおり、それに続いてイベントが実行されます。これらのイベントは移動先画面に属しているため、アクティブな画面は移動先画面となり、DOMのactive-screen
クラスにはその画面の要素が割り当てられます。
移動先画面のRenderイベントの後、画面遷移が発生し、最後に古い画面がDOMから削除されます。つまり、移動先画面のRenderイベントと古い画面のDestroyイベントの間では、両方の画面のDOMが利用可能となっています。
画面またはブロックのデータを変更するとき
画面またはブロックのデータ要素の値を変更したときには必ず、アプリケーションが自動的にそれに反応します。そのため、Renderイベントがトリガーされ、データの影響を受けるUI要素が自動的に更新されます。Webアプリのように、UI要素を明示的にリフレッシュする必要はありません。
画面またはブロックのAggregateおよびデータアクションでは、UI要素は自動的に新しい値に更新されますが、クエリを明示的に再実行する必要があります。この処理は、ロジックでRefresh Dataフロー要素を使用して行うことができます。
データを取り出した後、After Fetchイベントが発生します。Aggregateまたはデータアクションから返されたデータは画面またはブロックのデータに属しており、それが変更されたことから、Renderイベントも発生します。
例として、連絡先の詳細とともに、その連絡先との通話履歴リストが表示されている画面を思い浮かべてみてください。通話履歴を取得するには、現在の連絡先IDが割り当てられた画面の変数値でフィルタリングされたAggregateを使用します。連絡先が変更されたときには、画面に新しい連絡先の詳細を表示するため、画面の変数は新しい連絡先IDを持つように修正されます。この新しい連絡先への通話履歴リストを取得するには、Aggregateを再実行する必要があります。そのために必要な処理は、ロジックでRefresh Dataフロー要素を呼び出し、それぞれのAggregateまたはデータアクションを選択することのみです。クエリから新しい通話履歴リストが返されたら、画面に表示されているリストが自動的に更新されます。
ブロックのパラメータを変更するとき
入力パラメータの1つが変更されたときにブロックの通知と更新を可能にするため、アプリケーションはブロックのParameters Changedイベントハンドラを実行します。このイベントハンドラの一般的なユースケースは、上記の画像に示されているとおり、入力パラメータに依存するAggregateまたはデータアクションを再実行することです。ここでは、カレンダーの日付が変更された後、クエリが再実行され、チャートの新しい値が取得されています。
入力パラメータはブロックのデータの一部であるため、Renderイベントもトリガーされますが、それはParameters Changedイベントの後になります。
Lifecycleイベントハンドラ
イベント | 説明 |
---|---|
On Initialize | ユーザーの画面へのアクセス権限を確認した後、画面に移動してデータを取り出す前に発生します。ブロックの場合は、画面移動の後に発生します。デフォルトデータを設定することにより、画面またはブロックを初期化するために使用できます。 |
On Ready | 画面またはブロックのDOMの準備が完了した後、画面の遷移が開始する前に発生します。 |
On Render | 画面またはブロックのOn Readyイベントハンドラの実行直後、および画面またはブロックのデータが変更するたびに発生します。一部のサードパーティコンポーネントを更新するために使用できます。 |
On After Fetch | Aggregateまたはデータアクションがデータの取り出しを完了した後、そのデータが画面またはブロックに描画される前に発生します。読み出したデータを処理するために使用できます。 |
On Parameters Changed | 親である画面またはブロックが入力パラメータの1つを変更したとき、常にブロックで発生します。ブロック内の入力値に変更があっても、このイベントハンドラはトリガーされません。変数の更新など、ブロックのパラメータの変更に反応するために使用できます。 |
On Destroy | 画面またはブロックを消去し、DOMから削除する前に発生します。イベントリスナーの削除など、コンポーネントを破棄したときにロジックを実装するために使用できます。 |
On Initialize
On Initializeイベントハンドラは、ユーザーの画面へのアクセス権限を確認した後、画面に移動してデータの取り出しを開始する前に実行されます。
ブロックでは、サーバーアクションの呼び出しまたはローカルストレージの操作をこのフローに含めた場合には、このアクションの終了前にブロックの描画が開始する可能性があります。描画に影響を与える何らかの変数をこのフローに設定した場合には、問題が発生することがあります。
注記:
- 画面やブロックの描画が遅くなる可能性があるため、このイベントハンドラのアクションを簡潔に保ち、ローカルストレージのオペレーティングのような遅いアクションは避けてください。
- このアクションはデータが取り出される前に実行されるため、画面やブロックのデータにアクセスすることは避けてください。
このイベントハンドラを使用して実装できるユースケース:
- 入力に基づいて変数に値を割り当てる。
- 乱数など、JavaScriptでの計算に基づいて変数に値を割り当てる。
- ユーザーが画面を表示する権限を持たない場合にアプリケーションを他の画面にリダイレクトする(イベントハンドラが画面に属している場合にのみ可能)。
- 画面の入力に基づいて子ブロックのパラメータに値を割り当てる。
- JavaScriptのウィンドウオブジェクトの変数にアクセスする。
On Ready
On Readyイベントハンドラは、画面またはブロックの準備が完了したとき、つまり、DOMの準備が完了したとき、最初の描画後に実行されます。ブロックでは、このイベントは親である画面またはブロックの同一イベントの前に発生します。画面またはブロックをすばやく滑らかに描画するため、このイベントは、画面の遷移が完了する前であってもトリガーされます。
注記:
- このイベントがトリガーされると、前の画面と現在の画面のDOMがロードされます。作成中の画面に対する操作となるよう、HTMLの
active-screen
クラスを持つdiv
要素に対してのみロジックを実行します。 - 画面やブロックの描画が遅くなる可能性があるため、このイベントハンドラのアクションを簡潔に保ち、サーバーリクエストのような遅いアクションは避けてください。
- このアクションはデータが取り出される前に実行されるため、画面やブロックのデータにアクセスすることは避けてください。これらのデータに対する何らかのロジックを開発する必要がある場合は、それぞれのAggregateまたはデータアクションのOn After Fetchイベントハンドラを使用します。
このイベントハンドラを使用して実装できるユースケース:
- DOMを必要とするサードパーティコンポーネントを初期化する。
- DOM要素にリスナーを追加する。
- 入力ウィジェットにフォーカスを設定する。
- JavaScriptのウィンドウオブジェクトにリスナーを追加する。
On Render
On Renderイベントハンドラは、画面またはブロックが描画された後に必ず実行されます。つまり、画面またはブロックが開かれたとき(On Readyイベントハンドラの実行直後)、および画面のデータに何らかの変更があったときです。ブロックでは、このイベントは親である画面またはブロックの同一イベントの前に発生します。このイベントハンドラを使用して、プログレスバーなどのサードパーティコンポーネントを更新できます。
注記:
- 画面またはブロックのデータの変更は避けてください。それは、このデータが変更するたびにOn Renderイベントがトリガーされ、アプリの実行が無限ループになる可能性があるためです。
- 画面やブロックの描画が遅くなる可能性があるため、このイベントハンドラのアクションを簡潔に保ち、サーバーリクエストのような遅いアクションは避けてください。
- 画面またはブロックを初めて描画するときには、画面またはブロックのデータにアクセスすることは避けてください。これは、データがすでに取り出されているという保証がないためです。これらのデータに対する何らかのロジックを開発する必要がある場合は、それぞれのAggregateまたはデータアクションのOn After Fetchイベントハンドラを使用します。
このイベントハンドラを使用して実装できるユースケース:
- 画面またはブロックのデータの変更を処理して、サードパーティコンポーネントを更新する。
- On Readyイベントハンドラと同じユースケース。
On After Fetch
On After Fetchイベントハンドラは、Aggregateまたはデータアクションがデータの取り出しを完了した直後に実行されます。Aggregateまたはデータアクションにはそれぞれ独自のAfter Fetchイベントハンドラがあるため、そのデータソースから取得されたデータに対して処理を行うロジックを実装できます。
注記:
- On After Fetchイベントハンドラが実行されているときは、データはすでに取得済みで利用できる状態ですが、ウィジェットとは結び付けられていません。つまり、まだウィジェットは更新されていません。
このイベントハンドラを使用して実装できるユースケース:
- クエリから返された最初または最後のレコードを変数に割り当てる。
- マスターと詳細が組になったパターンで、クエリを繰り返してリストの一覧を入力する。
- 他のクエリに依存しているクエリの場合は、このイベントハンドラを使用して依存するAggregateをトリガーすることができます。
On Parameters Changed
On Parameters Changedは、親である画面またはブロックがそのブロックの入力を変更した後に実行されるブロックに対してのみ適用されるイベントハンドラです。ブロックが他のブロックの中にあり、外側のブロックの入力を変更すると入れ子になった内側のブロックの入力がその影響を受ける場合、外側のブロックのOn Parameters Changedイベントハンドラは、内側のブロックの同じイベントが開始される前に実行されます。このイベントハンドラを使用して、変数の更新やAggregateおよびデータアクションの再実行に伴う、入力パラメータの変更にブロックを適合させることができます。
このイベントハンドラを使用して実装できるユースケース:
- 入力パラメータに依存するAggregateまたはデータアクションをリフレッシュする。
- 入力パラメータに依存する変数を再計算する。
On Destroy
On Destroyイベントハンドラは、画面またはブロックが消去されるときに実行されます。画面の場合、新しい画面への遷移が完了したときにこのイベントが発生します。ブロックの場合、ブロックがDOMから削除される前にこのイベントが発生します。このイベントは、上位から下位の順にトリガーされます。入れ子になったブロックを持つ画面の場合、イベントは最初に画面で発生してから、次に外側のブロック、その後に入れ子のブロックで発生します。このイベントハンドラを使用して、イベントリスナーの削除などの画面またはブロックの足跡を消すロジックを実装できます。
注記:
- このイベントがトリガーされると、現在の画面と移動先画面のDOMがロードされます。消去中の画面に対する操作となるよう、HTMLのactive-screenのクラスを持つdiv要素に対してのみロジックを実行します。
- 画面やブロックの削除が遅くなる、あるいは画面を終了する場合には次の画面のロードが遅くなる可能性があるため、このイベントハンドラのアクションを簡潔に保ち、サーバーリクエストのような遅いアクションは避けてください。
このイベントハンドラを使用して実装できるユースケース:
- サードパーティコンポーネントの消去アクションを呼び出す。
- DOMを消去して、プラグインを再実行する。
- JavaScriptリスナーを削除する。