Rich UI での動的ロード
すべての Rich UI ハンドラーを単一の HTML ファイルにデプロイする代わりに、実行時の Rich UI ハンドラー・コードのダウンロードを制御することができます。 これは大規模なアプリケーションの場合、スケーラビリティーとパフォーマンスにおいてかなりの利点があります。
それぞれの動的ロードは非同期です。 ロードの完了時に応答するリスナー関数をコードし、ロードが完了するまでは、ユーザーは Web ページとの対話を続行します。
- 型の参照を使用する。以下に例を示します。
// a simple declaration mySecondary Secondary{}; // the as keyword, in a usage described later in this topic mySecondary Secondary = theHandler as Secondary; - 実行時にのみ解決される引用符付きストリングを使用する。以下に例を示します。
handler MainHandler type RUIhandler {onConstructionFunction = start } function start() // Load the first page DynamicLoader.loadHandler("myPkg.Secondary"); end
- DynamicLoader.loadHandler 関数を呼び出します。
- EGL デプロイメント記述子を構成する。次の 2 つの目的があります。
- DynamicLoader.loadHandler の呼び出しで指定するハンドラーを特定するには、以下のようにします。 引数として使用されるストリングは、実行時にのみ有意です。 EGL デプロイメント記述子で同じハンドラーを識別することで、実行時のロードにハンドラーを使用できます。
- ハンドラーが即時ダウンロード・コード に組み込まれないようにします。これは例えば、最初にダウンロードされる HTML ファイルに含まれるコードなどのような、一度にダウンロードされるロジックです。 あるハンドラーが 2 番目のハンドラーを動的にロードし、それがさらに 3 番目のものを動的にロードする場合、2 番目のハンドラーとともにダウンロードされるのは、2 番目のハンドラーのパーツとウィジェットのみです。 3 番目のハンドラーは、即時にダウンロードされるコード内にはありません。
型の参照を指定し、動的ロード用の EGL デプロイメント記述子を構成しない場合、型の参照によって、参照されるハンドラーは即時ダウンロード・コードに組み込まれます。
後述のサンプル・コードで示すとおり、型の参照は、動的にロードされるハンドラーで、コードがフィールドまたは関数に直接アクセスする場合に必要です。 ただし、コードが、動的にロードされるハンドラーの initialUI プロパティーに割り当てられたウィジェット配列にのみアクセスする場合は、型の参照は不要です。
動的ロードは、ModuleLoaderService という EGL 専用サービスにより実行時に処理されます。 この製品の将来のバージョンで変更される可能性がある内部の詳細を処理するため、このサービスは変更しないでください。
動的ローダーのサンプル使用については、『EGL Dojo ウィジェット』を参照してください。特にそこで説明されている GalleryDynamicLoading.egl ファイルの説明を参照してください。
DynamicLoader の関数
- loadHandler (handlerName String in)
この関数はハンドラーをロードします。
- handlerName
- 動的にロードされるハンドラーの完全修飾名。これについては前述の例に示されています。
- loadHandlerNoInstantiation (handlerName String in)
この関数は、ハンドラー型定義をロードしますが、ハンドラー・インスタンスはロードしません。 この関数は、ランタイムのパフォーマンスを向上させるために使用できます。 例えば、ハンドラー・タイプをアプリケーションで使用可能にするとしても、ハンドラー自体は、ハンドラーを必要とするメニュー項目をユーザーがクリックした場合にのみ作成されるようにできます。
- handlerName
- 動的にロードするハンドラーの完全修飾名。
- unloadHandler (handlerName String in)
この関数は、ハンドラーをアンロードしますが、そのハンドラーのインスタンスは破棄しません。 EGL ライブラリーはアンロードできません。これはアプリケーションが終了するまで使用できます。
ハンドラー・インスタンスは、以下の説明のいずれかが当てはまる場合は、メモリーから除去できません。- ハンドラーが、メモリーから除去されていない別のハンドラーで、型により参照されている。
- ハンドラーが Infobus によりサブスクライブされている。これについては『Rich UI Infobus』で説明しています。
たいていの場合、メモリーは EGL ランタイム・コードにより解放されます。 ただし、『Rich UI メモリー管理』のトピックでは、さらに高度なメモリー管理を行う方法について説明します。
- handlerName
- アンロードするハンドラーの完全修飾名。
- showDebugView()
この関数により、動的ローダーの内部で生じていることを示す詳細が表示されます。 これはメインのハンドラーの on-construction 関数に設定することができます。
DynamicLoader リスナー配列
function start()
// Set handler for the event that the page has been loaded
DynamicLoader.loadDoneListeners ::= processLoadDone;
DynamicLoader.loadHandler("myPkg.Secondary");
end
function processLoadDone (event HandlerLoadedEvent in)
// attach the initialUI widgets to the current page.
// this step does not require use of a type reference.
div.children = event.initialUI;
// access a function in the loaded handler
theHandler any = event.theHandler;
// the use of a handler (or other container) of type any requires
// a type reference so that your code can directly access a field
// or function that is embedded in that container
if (theHandler isa Secondary)
p1 Page1 = theHandler as Secondary;
p1.doTask();
end
end
record HandlerLoadedEvent
// The name of the handler
name String;
// The widgets defined by the Rich UI handler.
initialUI Widget[];
// A reference to the Rich UI handler
theHandler any;
end
- DynamicLoader.loadDoneListenersこの配列は、ハンドラーのロード後に呼び出される一連のリスナーを指定します。 委譲パーツについて、以下に示します。
delegate LoadDoneListener (event HandlerLoadedEvent in) end- event
- これについては前述しています。 ただし、loadHandlerNoInstantiation 関数を呼び出したことに応じてリスナーが実行中である場合、initialUI パラメーターは空の配列を受け取り、theHandler パラメーターはヌルを受け取ります。
- DynamicLoader.loadFailListeners
この配列は、ロードが失敗した場合に呼び出される一連のリスナーを指定します。 委譲パーツについて、以下に示します。
delegate LoadFailListener (handlerName string in, msg string in) end- handlerName
- ロードに失敗したハンドラーの完全修飾名。
- msg
- エラー・メッセージ。
以下に例を示します。function start() DynamicLoader.loadFailListeners ::= processLoadFail; DynamicLoader.loadHandler("myPkg.Secondary"); end Function processLoadFail (handlerName string in, msg string in) Syslib.writeStdErr(handlerName + “ failed to load. ” + msg); end - DynamicLoader.loadInfoListeners
この配列は、動的ローダーから呼び出すリスナーのセットを指定し、実行時のダウンロードおよびアンロード動作のトレースに使用されます。 このセットは、すべてのダウンロードされたまたはアンロードされたリソース に対して一度だけ呼び出されます。これは以下のいずれかの単位にすることができます。
- パーツ:
- Rich UI ハンドラー
- 基本ハンドラー
- ウィジェット
- ライブラリー (Rich UI プロパティー・ライブラリーを含む)
- レコード
- その他のリソース:
- JavaScript には、グローバルに定義されているかまたは外部型で参照されているファイルが含まれます。
- Rich UI プロパティー・ライブラリーに関連するプロパティー・ファイル
- EGL デプロイメント記述子に関連するサービス・バインディング・ファイル
委譲パーツについて、以下に示します。delegate LoadInfoListener (handlerName string, resourceName string, code string, msg string) end- handlerName
- ロードまたはアンロード関数に渡されたハンドラーの完全修飾名。
- resourceName
- ダウンロードまたはアンロードされたリソースの名前。
- code
- 以下のコードの 1 つ。それぞれは情報のタイプを示します。
- DynamicLoader.INFO_LOAD は、リソースがロードされたことを示します。
- DynamicLoader.INFO_UNLOAD は、リソースがアンロードされたことを示します。
- DynamicLoader.INFO_UNLOAD_SKIP は、(例えばリソースがライブラリーであるなどの理由で) リソースがアンロードされなかったことを示します。
- DynamicLoader.INFO_DEBUG は、動的ローダーからの汎用メッセージです。
- msg
- メッセージ。
以下に例を示します。function start() DynamicLoader.loadInfoListeners ::= processLoadInfo; DynamicLoader.loadHandler("myPkg.Secondary"); end function processLoadInfo (handlerName string, resourceName string, code string, msg string) if (code == DynamicLoader.INFO_UNLOAD) Syslib.writeStdErr(resourceName + “ unloaded.”); end end - パーツ:
ハンドラー・インスタンス
function createPage1() returns (Secondary)
anotherPage1 Secondary = new Secondary{};
return(anotherPage1);
end
handler MainHandler type RUIhandler {onConstructionFunction = start }
// error!
anotherPage1 Page1 = new Secondary{};
end
実行時に CSS ファイルを使用する際の考慮事項
EGL デプロイヤーがハンドラー用の HTML ファイルを作成する場合、このファイルには Rich UI アプリケーションで使用されるすべての CSS ファイルのリストが含まれます。 CSS ファイルは動的にはロードされません。
- 最上位レベルのものは、最上位ハンドラー内の定義です。
- 次に高いレベルのものは、HTML ファイル内の他のハンドラーの定義です。
- 最低のレベルのものは、動的にロードされたハンドラーの定義です。
Rich UI エディターの「プレビュー」ペインを使用する際の考慮事項
- ワークベンチは、編集中のハンドラーで型によって参照されるすべてのリソース、または 2 次レベルなどのハンドラーの 1 つにより参照されるハンドラーの型で参照されるすべてのリソースを含む HTML ファイルを、任意の参照レベルに対応するように作成します。
- 動的にロードされる唯一のハンドラーは、型参照ではなくストリングにより参照されるものです。
- 動的ロード・ハンドラーで指定される CSS および組み込みファイルは、「プレビュー」ペインでは使用できません。 それらのファイルは、編集中のハンドラーから、または編集中のハンドラーから型参照で直接的あるいは間接的にロードされるハンドラーから参照する必要があります。
- 別の方法では参照しないとしても、JavaScript ランタイム・ファイルの処理が必要になります。
例えば、ハンドラー A が、EGL Dojo ウィジェットを使用せずにハンドラー B をストリングによってのみ参照する場合に、ハンドラー B が EGL Dojo ウィジェットを使用するのであれば、ハンドラー A の includeFile プロパティーは、Dojo ランタイム・コードを参照するように設定する必要があります。これについては以下に示します。
{ includeFile = "config/includeDojo.html" }