Rich UI での動的ロード

すべての Rich UI ハンドラーを単一の HTML ファイルにデプロイする代わりに、実行時の Rich UI ハンドラー・コードのダウンロードを制御することができます。 これは大規模なアプリケーションの場合、スケーラビリティーとパフォーマンスにおいてかなりの利点があります。

それぞれの動的ロードは非同期です。 ロードの完了時に応答するリスナー関数をコードし、ロードが完了するまでは、ユーザーは Web ページとの対話を続行します。

背景情報として、あるハンドラーで別のハンドラーを、以下の 2 とおりの方法のいずれかで参照できることを考慮します。
ハンドラーを実行時にのみアプリケーション・サーバーからロードするには、以下のようにします。

型の参照を指定し、動的ロード用の EGL デプロイメント記述子を構成しない場合、型の参照によって、参照されるハンドラーは即時ダウンロード・コードに組み込まれます。

後述のサンプル・コードで示すとおり、型の参照は、動的にロードされるハンドラーで、コードがフィールドまたは関数に直接アクセスする場合に必要です。 ただし、コードが、動的にロードされるハンドラーの initialUI プロパティーに割り当てられたウィジェット配列にのみアクセスする場合は、型の参照は不要です。

動的ロードは、ModuleLoaderService という EGL 専用サービスにより実行時に処理されます。 この製品の将来のバージョンで変更される可能性がある内部の詳細を処理するため、このサービスは変更しないでください。

さらに詳しい説明は、以下のセクションにあります。

動的ローダーのサンプル使用については、『EGL Dojo ウィジェット』を参照してください。特にそこで説明されている GalleryDynamicLoading.egl ファイルの説明を参照してください。

DynamicLoader の関数

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 リスナー配列

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
以下に示すのは、HandlerLoadedEvent レコード・パーツです。これは processLoadDoneevent パラメーターから使用可能なものを識別します。
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 ライブラリーが提供するリスナーと、それに関連する委譲パーツです。
  • 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 ファイルは動的にはロードされません。

CSS 定義の優先順位の順序は、以下のとおりです。
  • 最上位レベルのものは、最上位ハンドラー内の定義です。
  • 次に高いレベルのものは、HTML ファイル内の他のハンドラーの定義です。
  • 最低のレベルのものは、動的にロードされたハンドラーの定義です。

Rich UI エディターの「プレビュー」ペインを使用する際の考慮事項

Rich UI エディターの「プレビュー」ペインでハンドラーを実行する場合には、以下の規則が適用されます。
  • ワークベンチは、編集中のハンドラーで型によって参照されるすべてのリソース、または 2 次レベルなどのハンドラーの 1 つにより参照されるハンドラーの型で参照されるすべてのリソースを含む HTML ファイルを、任意の参照レベルに対応するように作成します。
  • 動的にロードされる唯一のハンドラーは、型参照ではなくストリングにより参照されるものです。
「プレビュー」ペインで動的にロードされるハンドラーの場合は、以下の考慮事項が適用されます。
  • 動的ロード・ハンドラーで指定される CSS および組み込みファイルは、「プレビュー」ペインでは使用できません。 それらのファイルは、編集中のハンドラーから、または編集中のハンドラーから型参照で直接的あるいは間接的にロードされるハンドラーから参照する必要があります。
  • 別の方法では参照しないとしても、JavaScript ランタイム・ファイルの処理が必要になります。 例えば、ハンドラー A が、EGL Dojo ウィジェットを使用せずにハンドラー B をストリングによってのみ参照する場合に、ハンドラー B が EGL Dojo ウィジェットを使用するのであれば、ハンドラー A の includeFile プロパティーは、Dojo ランタイム・コードを参照するように設定する必要があります。これについては以下に示します。
    { includeFile = "config/includeDojo.html" }

フィードバック