Oracle® Fusion Middleware Oracle Application Development FrameworkによるFusion Webアプリケーションの開発 12c (12.1.3) E59441-03 |
|
![]() 前 |
![]() 次 |
この章では、Fusion Webアプリケーション内のADF Facesリージョン間の通信を円滑化する、コンテキスト・イベントの作成方法、公開方法およびサブスクライブ方法について説明します。ここでは、イベントを宣言的に作成する方法と、マネージドBeanおよびJavaScriptをプログラム的に使用する方法について説明します。
この章の内容は次のとおりです。
コンテキスト・イベント・フレームワークは、ページ内のリージョン間の通信を可能にします。このフレームワークにより、ページ上の様々なリージョンによって生成および使用される各イベントを、ページ上でマップできます。JDeveloperを使用して、ページ定義ファイルによって宣言的にイベントを公開できます。同様に、ページ定義ファイルから、これらのイベントを宣言的にサブスクライブできます。パラメータをイベントとともに渡し、イベントに応答するハンドラを実装します。コンテキスト・イベントを作成するその他の方法には、マネージドBeanの使用、JavaScriptの使用などがあります。コンテキスト・イベントでは、リージョンがパラメータを受け取るために、リージョンをリフレッシュする必要はありません。
コンテキスト・イベントは、ADFビジネス・コンポーネントが発生させるビジネス・イベントや、UIコンポーネントが発生させるイベントとは異なります。これらのタイプのイベントの説明は、『Oracle ADF FacesによるWebユーザー・インタフェースの開発』を参照してください。ただし、コンテキスト・イベントは、UIイベントと関連付けて使用できます。この場合、UIイベントにより起動されるアクション・リスナーが、メソッド・アクション・バインディングを起動し、これによりイベントを生成できます。
ページまたはページ内のリージョンは、ページの他の場所からの情報または異なるリージョンからの情報を必要とすることがよくあります。情報を取得するためにパラメータを渡すことは可能ですが、それはパラメータが既知であり、EL式でページにアクセスできる入力である場合のみ意味を持ちます。また、パラメータ値が変化した場合にタスク・フローを再起動する必要があるときに、パラメータは便利です。
ただし、複数のページ・フラグメントを持つタスク・フローがあり、ページ・フラグメントには、フロー内のあるページへの入力として使用できる様々な興味深い値が含まれているとします。パラメータを使用して値を渡す場合、タスク・フローはすべてのフラグメントの興味深い各値を結合するための出力パラメータを公開する必要があります。そのかわり、必要な情報を含む各フラグメントに対し、ページを送信すると発生するコンテキスト・イベントを定義できます。これにより、情報を必要とするページやフラグメントは様々なイベントをサブスクライブし、このイベントを介して情報を受け取ることができます。
ADFタスク・フローについてのSummitサンプル・アプリケーションでは、選択した兵品の在庫を表示するために、コンテキスト・イベントがメイン・ページの「Inventory Control」タブで使用されています。ユーザーが「Inventory Control」タブを選択すると、2つのリージョンが並んで表示されます。一方のリージョンには、showProducts.jsff
ページ・フラグメントが収容されます。このページ・フラグメントには、製品在庫の表が含まれています。もう一方のリージョンには、showInventory.jsff
ページ・フラグメントが収容されます。このページ・フラグメントには、各倉庫の製品在庫割合示すDVTチャートが含まれています。図40-1に、製品リージョンと在庫リージョンを表示する「Inventory Control」タブを示します。
製品リージョンには、showProducts.jsff
ページ・フラグメントを利用するshow-products-task-flow
タスク・フローが含まれています。在庫リージョンには、showInventory.jsff
ページ・フラグメントを利用するproduct-inventory-task-flow
タスク・フローが含まれています。
メイン・ページのindex.jsff
は、両方のリージョンの親ページになります。これらのリージョンは、af:panelTabbed
レイアウト・コンポーネントの子に配置されています。
コンテキスト・イベントは、製品リージョンから在庫リージョンに渡されるため、選択した製品のDVTチャートがshowInventory-task-flow
で表示できるようになります。「プロパティ」ウィンドウを使用してプロデューサ・コンポーネントのイベントを作成すると、プロデューサのページ定義ファイルにイベントが登録されます。Summit ADFサンプル・アプリケーションでは、productSelected
イベントがshowProductsPageDef.xml
ファイルに登録されます(例40-1を参照)。
例40-1 プロデューサ・ページ定義ファイル内のコンテキスト・イベント
<tree IterBinding="ProductVO1Iterator" id="ProductVO1"> <nodeDefinition DefName="oracle.summit.model.views.ProductVO" Name="ProductVO10"> <AttrNames> <Item Value="Id"/> <Item Value="Name"/> <Item Value="ShortDesc"/> <Item Value="LongtextId"/> <Item Value="ImageId"/> <Item Value="SuggestedWhlslPrice"/> <Item Value="WhlslUnits"/> </AttrNames> <events
xmlns="http://xmlns.oracle.com/adfm/contextualEvent"> <event name="productSelected" eventType="Currency Change Event" customPayLoad="#{bindings.Id.inputValue}"/> </events
> </nodeDefinition> </tree>
ページ定義ファイルの概要エディタを使用してイベントにサブスクライブすると、プロデューサとコンシューマとの間でイベントをマップするeventMapが作成されます。
Summit ADFサンプル・アプリケーションでは、eventMapはコンシューマのページ定義ファイルに作成されます(例40-2を参照)。
例40-2 showInventoryPageDef.xmlファイルのイベント・マップ
<eventMap xmlns="http://xmlns.oracle.com/adfm/contextualEvent"> <event name="productSelected"> <producer region="*"> <consumer handler="populateInventoryForProduct" region=""> <parameters> <parameter name="productId" value="${payLoad}"/> </parameters> </consumer> </producer> </event> </eventMap>
実行時に、ユーザーが、show-products-task-flow-definition
とshowProducts.jsff
ページ・フラグメントに移動すると、在庫のある製品の表が表示されます。ユーザーがリストから製品を選択すると、通貨変更イベントが起動されます。その結果として、productSelected
コンテキスト・イベントがブロードキャストされます。この例では、選択した製品のproductId
を含むpayLoad
パラメータが、イベントとともに渡されます。
その後、このイベントは、product-inventory
タスク・フローとそのハンドラのpopulateInventoryForProduct()
メソッドで使用されます。このメソッドでは、payLoad
パラメータを使用して、どの製品の在庫情報をDVTコンポーネントに表示するかを決定します。
このイベント・ハンドラのコードを作成する必要があります。Summit ADFサンプル・アプリケーションの場合は、在庫データがInventoryVOビュー・オブジェクト
に含まれているため、InventoryVOImpl.java
ファイルにpopulateInventoryForProduct()ハンドラを追加します(例40-3を参照)。
例40-3 Summit ADFサンプル・アプリケーションのpopulateInventoryForProductイベント・ハンドラ
public void populateInventoryForProduct( String productId ) { applyViewCriteria(getViewCriteria("InventoryVOCriteria")); setinputProductId( productId ); executeQuery(); } /** * Returns the variable value for Variable. * @return variable value for Variable */ public String getinputProductId() { return (String)ensureVariableManager().getVariableValue("inputProductId"); } /** * Sets <code>value</code> for variable Variable. * @param value value to bind as Variable */ public void setinputProductId(String value) { ensureVariableManager().setVariableValue("inputProductId", value); }
イベントは、イベントを発生させるページまたはリージョン(作成者)のページ定義ファイルで構成されます。イベントに基づいた処理を実行するコンシューマをプロデューサと関連付けるには、コンシューマ側のページまたは親ページのページ定義ファイルにイベント・マップを作成します。(親ページは両方のリージョンを含むページです)。使用ページが動的リージョン内にある場合、イベント・マップを使用ページのページ定義ファイル内に配置し、プロデューサの属性リージョンを"*"に設定する必要があります。属性リージョンを"*"に設定するのは、設計時、フレームワークはプロデューサへの相対パスを決定できないためです。
コンテキスト・イベントは、アクション・バインディング、メソッド・アクション・バインディング、値属性バインディング、またはレンジ・バインディング(表、ツリー、またはリスト・バインディング)に対して発生させることができます。また、条件付きでイベントを発生させ、EL式を使用して条件付きでイベントを処理することもできます。
アクション・バインディングとメソッド・アクション・バインディングの場合、アクションまたはメソッドの実行時にイベントは発生します。payLoad
には、メソッドの戻り値が含まれます。また、ボタンのクリックやメニューからの選択などのADF Facesイベントからコンテキスト・イベントを発生させることもできます。イベントを定義するeventBinding
がページ定義内に作成されます。
値属性バインディングの場合、イベントはバインディング・コンテナによってトリガーされ、属性が正常に設定された後に発生します。payLoad
はDCBindingContainerValueChangeEvent
のインスタンスであり、新規の値、古い値、プロデューサ・イテレータ、バインディング・コンテナおよびソースへのアクセスを提供します。カスタム・データ・オブジェクトをポイントするようにpayLoad
プロパティを変更すると、payLoad
参照はかわりにオブジェクトを返します。例40-4は入力コンポーネントと関連付けられている属性値バインディング内部の値の変更イベントを示します。このページでユーザーがLAST_NAME
の値を変更すると、イベントvalueChangeEvent
がディスパッチされます。
例40-4 ページ定義ファイルの値属性イベント
<attributeValues IterBinding="DeptView1Iterator" id="Dname" xmlns="http://xmlns.oracle.com/adfm/jcuimodel"> <events xmlns="http://xmlns.oracle.com/adfm/contextualEvent"> <event name="valueChangeEvent"/> </events> <AttrNames xmlns="http://xmlns.oracle.com/adfm/uimodel"> <Item Value="LAST_NAME"/> </AttrNames> </attributeValues> </bindings> <eventMap xmlns="http://xmlns.oracle.com/adfm/contextualEvent"> <event name="valueChangeEvent"> <producer region="LAST_NAME"> <consumer region="" handler="consumeEvent"/> </producer> </event> </eventMap>
範囲バインディング(ツリー、表、リスト)の場合、イベントは現行の変更が正常に行われた後に発生します。payLoad
はDCBindingContainerValueChangeEvent
のインスタンスであり、新規の値、古い値、プロデューサ・イテレータ、バインディング・コンテナおよびソースへのアクセスを提供します。例40-2に、範囲バインディングに関連付けられた通貨変更イベントのイベント・マップを示します。
値属性バインディングおよび範囲バインディングのコンテキスト・イベントは、ナビゲーションの変化によってトリガーすることもできます。たとえば、ツリー表バインディングの内部にイベントを作成した場合、ユーザーがページでこのツリーの別ノードを選択したときに、このイベントがディスパッチされます。
「プロパティ」ウィンドウの「動作」セクションの下にある「コンテキスト・イベント」セクションを使用すると、コンテキスト・イベントを作成および公開できます。図40-2に示すように、「コンテキスト・イベント」パネルは、ページから適切なコンポーネントまたはリージョンを選択した場合にのみ表示されます。
コンテキスト・イベントのサブスクライブには、ページ定義ファイルの「コンテキスト・イベント」タブの「サブスクライバ」セクションにある概要エディタを使用します(図40-3を参照)。
リージョンと親ページ間の通信パターンには、親対リージョン、リージョン対親、リージョン対リージョンの3種類があります。コンテキスト・イベント・フレームワークは、これら3つのシナリオすべてに対応する、非常に強力な通信実装です。コンテキスト・イベントでは、リージョンが入力パラメータを使用するために、リージョンをリフレッシュする必要はありません。
ADFリージョン間で通信を行うには、コンテキスト・イベントを使用する必要があります。ADFタスク・フロー・パラメータを使用してリージョン間の通信もできますが、この場合、リージョン間に直接的な依存性が生じてしまう可能性があります。静的なリージョンに対しては、ADFタスク・フロー・パラメータの使用が適切な場合もありますが、コンテキスト・イベントを使用すると、リージョン間の独立した通信を実装できます。
たとえば、従業員情報を入力するためのフォームを保持するリージョンがページに含まれるとします。ユーザーが従業員IDを更新し、送信ボタンを押すと、値変更コンテキスト・イベントが発生し、従業員ID値がpayLoadとして渡されます。同じページ上の別のリージョンがこのイベントをサブスクライブして使用することで、コンテキスト・イベントとともに渡されたpayLoadの情報に基づき、選択された従業員に対する部署情報を表示できます。
コンテキスト・イベントの処理を開始する前に、その他のADF機能について理解しておいてください。次に、関連する他の機能へのリンクを示します。
ADFタスク・フロー・パラメータを使用して、ADFリージョン間で通信を行うこともできます。タスク・フローとリージョンの使用に関する詳細は、第23章「タスク・フローのリージョンとしての使用」を参照してください。
コンテキスト・イベントを作成するには、まず、メソッド・アクション、アクション、値属性、またはリスト・バインディングに基づいて、プロデューサにイベントを作成し、公開します。コンシューマで、このイベントをサブスクライブし、これを処理するためのハンドラを作成します。
通常、タスク・フローおよびビュー・アクティビティを含むリージョンを持つ親ページを作成します。リージョンの1つには、もう1つのリージョンのコンシューマ・イベント・ハンドラのために公開されるコンテキスト・イベントを作成します。タスク・フローとリージョンの使用に関する詳細は、第23章「タスク・フローのリージョンとしての使用」を参照してください。
注意: コードから(マネージドBeanの内部などから)アクション・コンテキスト・イベントを公開することもできます。EventDispatcher のインスタンスを戻すgetBindingContainer().getEventDispatcher を使用します。EventDispatcher には、コンテキスト・イベントをプログラミングによって発生させるために使用できるパブリックAPIがあります。 |
「プロパティ」ウィンドウを使用して、コンテキスト・イベントを生成するページにコンテキスト・イベントを作成します。つまり、プロデューサのページが、コンテキスト・イベントを生成するページになります。たとえば、あるページのボタンをクリックすると、別のコンポーネントで利用されるコンテキスト・イベントがトリガーされるとします。このボタンを含むページが、プロデューサのページになります。
始める前に:
コンテキスト・イベントの作成時に使用可能な各オプションについて理解しておくと役立ちます。詳細は、40.2項「コンテキスト・イベントの宣言的な作成」を参照してください。
また、コンテキスト・イベントで使用可能な各機能についても理解しておくと役立ちます。詳細は、40.1.2項「コンテキスト・イベントの追加機能」を参照してください。
次のタスクを完了する必要があります。
コンテキスト・イベントを作成するには:
コンテキスト・イベントを公開するページで、「データ・コントロール」パネルからコンポーネントをドラッグし、そのページにドロップします。
このコンポーネントで、イベントをトリガーすることになります。これには、メソッド・アクション、アクション、値属性またはリストのバインディング・イベントが必要です。
「プロパティ」ウィンドウで、「動作」セクションを開きます。
「イベントの発行」セクションで「追加」アイコンをクリックします。
コンテキスト・イベントの公開ダイアログで:
「新規イベントの作成」を選択します。
イベントの名前を入力します。
表、ツリーまたはツリー表のコンポーネントを使用している場合は、「ノード」フィールドが表示されます。このフィールドには、変更イベントの発生時にイベントを公開するノードを入力します。
ペイロード・データをコンシューマに渡す場合は、「次からカスタム値を渡す」を選択します。
payloadデータを渡す場合は、ドロップダウン・リストからデータ型を選択します。通常、このパラメータは、{$payLoad}になります。
たとえば、プロデューサ・ページからコンシューマ・ページに属性値を渡す場合は、「ページ・データ」を選択して、ツリー構造から目的の属性を選択します。
「呼出し条件」タブにEL式を入力して、条件付きでイベントを発生させることができます。
たとえば、式${bindings.LAST_NAME.inputValue == 'KING'}
を入力すると、顧客の姓が「KING」である場合のみ、イベントが発生します。
「OK」をクリックします。
イベントはこのページに作成されますが、コンポーネント・バインディングと関連付けるまで公開できません。
コンテキスト・イベントにサブスクライブするには、ページ定義ファイルの概要エディタを使用します。概要エディタには、現在のリージョンと、その子のリージョンが表示されます。コンテキスト・イベントにサブスクライブできるリージョンのみが表示されます。
始める前に:
コンテキスト・イベントの作成時に使用可能な各オプションについて理解しておくと役立ちます。詳細は、40.2項「コンテキスト・イベントの宣言的な作成」を参照してください。
また、コンテキスト・イベントで使用可能な各機能についても理解しておくと役立ちます。詳細は、40.1.2項「コンテキスト・イベントの追加機能」を参照してください。
次のタスクを完了する必要があります。
イベントをサブスクライブし、使用するには:
イベントとそのペイロード・データを処理するハンドラを作成します。
Summit ADFサンプル・アプリケーションでは、InventoryVOImpl.java
ファイルにコードを追加することで、InventoryVO
ビュー・オブジェクトにPopulateInventoryForProduct
ハンドラ・メソッドを作成します。
このメソッドは、BackOfficeAppModuleDataControl
アプリケーション・モジュール内にあります。
コンシューマ側のページには、イベントに応答するコンポーネントを追加します。
Summit ADFサンプル・アプリケーションでは、DVTコンポーネントをページに追加することで、各倉庫内の在庫を表示します。
このDVTコンポーネントは、PopulateInventoryForProduct
メソッドからデータを取得します。
「アプリケーション」ウィンドウで、イベント・マップを含めるページ定義ファイルをダブルクリックします。
Summit ADFサンプル・アプリケーションでは、showInventoryPageDef.xml
ページ定義ファイルにイベント・マップを含めます。
概要エディタの「バインディングと実行可能ファイル」タブをクリックし、「バインディング」セクションの「追加」アイコンをクリックします。
「項目の挿入」ダイアログで、methodActionを選択し、「OK」をクリックします。
「アクション・バインディングの作成」ダイアログで:
ハンドラを作成したデータ・コレクションを開きます。
ハンドラを選択します。
「OK」をクリックします。
概要エディタの「コンテキスト・イベント」タブで「サブスクライバ」をクリックし、「イベント・サブスクライバ」セクションの「追加」アイコンをクリックします。
「コンテキスト・イベントのサブスクライブ」ダイアログで:
イベント名を入力するか、「検索」アイコンをクリックして、「コンテキスト・イベントの選択」ダイアログを開きます。
「コンテキスト・イベントの選択」ダイアログが開かれている場合は、イベントをツリー構造から選択して「OK」をクリックします。
「パブリッシャ」ドロップダウン・リストから目的のプロデューサ、または「<任意>」を選択します。1つのコンテキスト・イベントに対して複数のプロデューサが存在することがあります。
<Any>を選択すると、コンシューマは、選択したイベントを生成するあらゆるプロデューサをサブスクライブできます。ページ定義ファイルで、producer
属性にはワイルドカード"*"が設定されます。プロデューサが動的リージョン内にある場合、サブスクライバがどのプロデューサからでも使用できるように、このフィールドを<Any>に設定する必要があります。
「範囲」フィールドの隣にある「ハンドラ」アイコンをクリックします。
「ハンドラの選択」ダイアログで、ツリー構造から目的のイベント・ハンドラを選択し、「OK」をクリックします。
このハンドラにパラメータが必要な場合は、「パラメータ」タブを選択し、「追加」をクリックしてから、パラメータとして名前/値ペアを入力します。
条件付きでイベントを処理する場合、ハンドル・タブを選択し、ハンドラがイベントを処理する条件を決定するEL式を入力します。
「OK」をクリックします。
注意: 「構造」ウィンドウでページ定義を右クリックし、「イベント・マップの編集」を選択し、イベント・マップを編集することができます。ページ定義ファイルまたは「プロパティ」ウィンドウで、イベントの属性を編集することもできます。 |
作成者のイベントを作成すると、JDeveloperはページ定義ファイルにevents
要素を追加します。各イベント名が子として追加されます。例40-5は、通貨変更イベントとしてプロデューサのページ定義ファイル内に定義されたproductSelected
イベントを示しています。
例40-5 プロデューサのイベント定義
<tree IterBinding="ProductVO1Iterator" id="ProductVO1"> <nodeDefinition DefName="oracle.summit.model.views.ProductVO" Name="ProductVO10"> <AttrNames> <Item Value="Id"/> <Item Value="Name"/> <Item Value="ShortDesc"/> <Item Value="LongtextId"/> <Item Value="ImageId"/> <Item Value="SuggestedWhlslPrice"/> <Item Value="WhlslUnits"/> </AttrNames> <events xmlns="http://xmlns.oracle.com/adfm/contextualEvent"> <event name="productSelected" eventType="Currency Change Event" customPayLoad="#{bindings.Id.inputValue}"/> </events> </nodeDefinition> </tree>
コンシューマのページ定義ファイルには、イベントに応答するメソッド・アクション・バインディングが作成されます。例40-6は、showInventoryPageDef
ページ定義ファイルに定義されたメソッド・アクション・バインディングです。
例40-6 ページ定義ファイル内のメソッド・アクションの定義
<methodAction id="populateInventoryForProduct" RequiresUpdateModel="true" Action="invokeMethod" MethodName="populateInventoryForProduct" IsViewObjectMethod="true" DataControl="BackOfficeAppModuleDataControl" InstanceName="data.BackOfficeAppModuleDataControl.InventoryVO1"> <NamedData NDName="productId" NDType="java.lang.String"/> </methodAction>
通貨の変更が発生すると、そのイベントは、イベントのコンシューマにブロードキャストされます。メソッド・アクションの定義は、コンシューマ側のページ定義ファイルで定義されます。
イベント・マップを構成すると、JDeveloperは対応するページ定義ファイルにイベント・マップのエントリを作成します。例40-7は、showproductstaskflowdefinition1
リージョンからproductinventorytaskflowdefinition1
リージョンにproductSelected
イベントをマップする、showInventoryPageDef
ページ定義ファイルのイベント・マップを示しています。また、showInventoryPageDef
ページ定義ファイルで定義されているpopulateInventoryForProduct
ハンドラ・メソッド・バインディングもマップしています。このハンドラは、payLoad情報(productID
が含まれる)を処理してDVTコンポーネントに渡すため、このコンポーネントは、その製品の倉庫内在庫を問合せできるようになります。
例40-7 コンシューマ側のページ定義ファイルのイベント・マップ
<eventMap xmlns="http://xmlns.oracle.com/adfm/contextualEvent"> <event name="productSelected"> <producer region="*"> <consumer handler="populateInventoryForProduct" region=""> <parameters> <parameter name="productId" value="${payLoad}"/> </parameters> </consumer> </producer> </event> </eventMap>
アプリケーション・レベル、またはページ・レベルで、子リージョンへのコンテキスト・イベントのディスパッチを制御できます。
始める前に:
コンテキスト・イベントの作成時に使用可能な各オプションについて理解しておくと役立ちます。詳細は、40.2項「コンテキスト・イベントの宣言的な作成」を参照してください。
また、コンテキスト・イベントで使用可能な各機能についても理解しておくと役立ちます。詳細は、40.1.2項「コンテキスト・イベントの追加機能」を参照してください。
イベントのディスパッチを無効化するには:
アプリケーション・レベルでイベントのディスパッチを無効化するには、例40-8
に示すように、adf-config.xml
ファイルのdynamicEventSubscriptions
プロパティをfalseに設定します。
プロデューサがワイルドカードであるイベント・マップを持つリージョンへのイベントのディスパッチを無効化できます。
例40-8 adf-config.xmlを使用して、アプリケーション・レベルのコンテキスト・イベント・ディスパッチを無効化
<?xml version="1.0" encoding="windows-1252" ?> <adf-config xmlns="http://xmlns.oracle.com/adf/config" xmlns:cef="http://xmlns.oracle.com/adfm/contextualEvent"> <cef:DynamicRegionEventsConfig dynamicEventSubscriptions="false"> </cef:DynamicRegionEventsConfig> </adf-config>
個々のページ・レベルでイベントのディスパッチを無効化するには、例40-9
に示すように、関連付けられたページ定義ファイル内でdynamicEventSubscriptions
プロパティをfalseに設定します。
コンテキスト・イベントがこのページや、その子のいずれにも渡されることはありません。
イベント・プロデューサとコンシューマの両方が同じページ定義ファイルに定義されている場合、対応するページの呼び出しおよびバインディング・コンテナの作成後、次の場合にイベントが発生します。
対応するメソッドまたはアクション・バインディングが実行される
値バインディングが正常に設定される
レンジ・バインディングの現行性が正常に設定される
メソッド・バインディングの場合、メソッド実行の結果がイベントのペイロードを形成し、イベントがキューイングされます。JSFライフサイクルのアプリケーションの起動フェーズで、キューイングされたすべてのイベントがディスパッチされます。バインディング・コンテナに関連付けられたイベント・ディスパッチャは、そのイベントに関連するコンシューマをイベント・マップで確認し、イベントをコンシューマに渡します(イベント・マップは同じページ定義ファイルの一部であるため、バインディング・コンテナにも含まれます)。
プロデューサとコンシューマが異なるリージョンに存在する場合、イベントは最初に同じコンテナ内の任意のコンシューマにディスパッチされ、次にイベント伝播が親バインディング・コンテナに委任されます。この処理は、親または最上位のバインディング・コンテナに達するまで続きます。最上位バインディング・コンテナに達した後、プロデューサがワイルドカード(*
)に設定されているページでリージョンを保持する子バインディング・コンテナに、イベントが再度ディスパッチされます。
コンテキスト・イベントの作成では、最初に作成者にイベントを作成します。続いてイベントのコンシューマを定義し、プロデューサとコンシューマをマッピングします。
始める前に:
コンテキスト・イベントの作成時に使用可能な各オプションについて理解しておくと役立ちます。詳細は、40.3項「コンテキスト・イベントの手動作成」を参照してください。
また、コンテキスト・イベントで使用可能な各機能についても理解しておくと役立ちます。詳細は、40.1.2項「コンテキスト・イベントの追加機能」を参照してください。
次のタスクを完了する必要があります。
コンテキスト・イベントを作成するには:
「アプリケーション」ウィンドウで、イベントのプロデューサ用のバインディングを含むページ定義ファイルをダブルクリックします。
作成者には、イベントの発行に使用される関連付けられたバインディングが必要です。たとえば、メソッドまたは操作が作成者になる場合、イベントは関連アクション・バインディングまたはメソッド・アクション・バインディングに含まれます。
「構造」ウィンドウで、プロデューサのバインディングを右クリックし、「バインディング名の中に挿入」→eventsまたは「バインディング名の中に挿入」→「コンテキスト・イベント」→eventsを選択します。
「構造」ウィンドウで、たった今作成されたevents要素を右クリックし、「eventsの中に挿入」→「event」を選択します。
「eventの挿入」ダイアログで、「名前」フィールドにイベント名を入力し、「終了」をクリックします。
これで、イベントが作成されます。デフォルトでは、関連するメソッドまたは操作の戻り値はすべて、イベントのペイロードとして取得され、ELでアクセス可能な変数${data.payLoad}
に格納されます。次に、イベントをコンシューマにマッピングし、コンシューマに渡す必要があるペイロードを構成する必要があります。
「アプリケーション」ウィンドウで、コンシューマ用のバインディングを含むページ定義ファイルをダブルクリックします。
このページが表すバインディング・コンテナは、含まれるバインディング・コンテナすべてを含む現在のスコープ(タスク・フロー・リージョンなど)からイベントへのアクセスを提供します。リージョンまたは他のネストされたコンテナがイベントを認識する必要がある場合、イベント・マップは使用リージョン内のページのページ定義に存在する必要があります。
「構造」ウィンドウで、ページ定義を表す最上位のノードを右クリックし、「イベント・マップの編集」を選択します。
注意: プロデューサ・イベントが埋込み動的リージョン内のページから発生する場合、イベント・マップ・エディタを使用してイベント・マップを編集できないことがあります。イベント・マップを手動で作成するには、ページ定義ファイルを編集するか、40.3項「コンテキスト・イベントの手動作成」で説明している「内部に挿入」の手順を使用します。 |
イベント・マップ・エディタで、「追加」アイコンをクリックして、イベント・エントリを追加します。
「新規EventMapエントリの追加」ダイアログ・ボックスで、次の操作を行います。
作成者ドロップダウン・メニューを使用して作成者を選択します。
「イベント名」ドロップダウン・メニューを使用してイベントを選択します。
使用者ドロップダウン・メニューを使用して使用者を選択します。これは、イベントを使用する実際のメソッドになります。
使用するメソッドまたは操作にパラメータが必要な場合は、「追加」アイコンをクリックします。
「パラメータ名」フィールドに、メソッドに必要なパラメータの名前を入力します。「パラメータ値」フィールドに値を入力します。これがイベントからのペイロードの場合は、${data.payLoad}
式を使用すると、この値にアクセスできます。ペイロードに複数のパラメータが含まれ、それらすべてを必要とする場合以外は、省略記号ボタンを使用して「式ビルダー」ダイアログを開きます。このダイアログを使用して、「ペイロード」ノードの下の特定のパラメータを選択できます。
また、「パラメータ」省略記号ボタンをクリックして、選択ダイアログを開くこともできます。
「OK」をクリックします。
イベント・マップ・エディタで、「OK」をクリックします。
マネージドBeanの内部など、コードからアクション・コンテキスト・イベントを公開することができます。
始める前に:
コンテキスト・イベントの作成時に使用可能な各オプションについて理解しておくと役立ちます。詳細は、40.4項「マネージドBeanを使用したコンテキスト・イベントの作成」を参照してください。
また、コンテキスト・イベントで使用可能な各機能についても理解しておくと役立ちます。詳細は、40.1.2項「コンテキスト・イベントの追加機能」を参照してください。
マネージドBeanを使用してコンテキスト・イベントを作成するには:
コンテキスト・イベントを生成するマネージドBeanのメソッドを作成します。
例40-10に、ボタンがクリックされたときにアクションを実行するマネージドBeanのコードを示します。myActionPerformed
メソッドが呼び出されると、payLoadとして"myString"を含むコンテキスト・イベントを生成するためのメソッドをコールします。
例40-10 コンテキスト・イベントを処理するマネージドBean
BindingContainer bc BindingContext.getCurrent().getCurrentBindingsEntry(); JUCtrlActionBinding actionBnd = (JUCtrlActionBinding)bc.getControlBinding("eventProducer"); ... ((DCBindingContainer)bc).getEventDispatcher().queueEvent(actionBnd. getEventProducer(),"myString");
プロデューサ・コンポーネントをマネージドBeanのメソッドにバインドします。
例40-11に、アクション・バインディングを起動するコマンド・ボタンに関連付けられた、プロデューサのコードを示します。このコードでのコンシューマは文字列を表示するoutputText
コンポーネントです。これらは両方とも同じページにあります。
例40-11 JSFのイベント・プロデューサとイベント・コンシューマ
<af:form id="f1"> <af:button value="eventProducerButton1" id="cb1" action="#{MyBean.myActionPerformed}"/> <af:panelLabelAndMessage label="#{bindings.return.hints.label}"id="plam1"> <af:outputText value="#{bindings.return.inputValue}" id="ot1"/> </af:panelLabelAndMessage> </af:form>
例40-12に示すとおり、このページ定義ファイルには、プロデューサのメソッド・アクション・バインディング、コンシューマおよびイベント・マップが含まれます
例40-12 イベント・プロデューサ、イベント・コンシューマおよびイベント・マップを含むページ定義
<executables> <variableIterator id="variables"> <variable Type="java.lang.String" Name="eventConsumer_return" IsQueriable="false" IsUpdateable="0" DefaultValue="${bindings.eventConsumer.result}"/> </variableIterator> </executables> <bindings> <methodAction id="eventProducer" InstanceName="AppModuleDataControl.dataProvider" DataControl="AppModuleDataControl" RequiresUpdateModel="true" Action="invokeMethod" MethodName="eventProducer" IsViewObjectMethod="false" ReturnName="AppModuleDataControl.methodResults.eventProducer_ AppModuleDataControl_dataProvider_eventProducer_result"> <events xmlns="http://xmlns.oracle.com/adfm/contextualEvent"> <event name="myEvent"/> </events> </methodAction> <methodAction id="eventConsumer" RequiresUpdateModel="true" Action="invokeMethod" MethodName="eventConsumer" IsViewObjectMethod="false" DataControl="AppModuleDataControl" InstanceName="AppModuleDataControl.dataProvider" ReturnName="AppModuleDataControl.methodResults.eventConsumer_ AppModuleDataControl_dataProvider_eventConsumer_result"> <NamedData NDName="str" NDValue="test" NDType="java.lang.String"/> </methodAction> <attributeValues IterBinding="variables" id="return"> <AttrNames> <Item Value="eventConsumer_return"/> </AttrNames> </attributeValues> </bindings> <eventMap xmlns="http://xmlns.oracle.com/adfm/contextualEvent"> <event name="myEvent"> <producer region="eventProducer"> <consumer region="" handler="eventConsumer"> <parameters> <parameter name="test" value="${data.payLoad}"/> </parameters> </consumer> </producer> </event> </eventMap>
リージョンに埋め込まれているバインドされたタスク・フローには、コンテキスト・イベントの潜在的なコンシューマとして公開する必要のある複数のビューがある場合があります。各ビューのプレーンJavaオブジェクト(POJO)、データ・コントロールおよびイベント・ハンドラを作成するかわりに、単一のPOJOと単一のデータ・コントロールを作成して、タスク・フロー内のすべてのビューのイベントを処理できます。
このアプローチでは、イベント・レシーバ・メソッドは、handleEvent
メソッドを呼び出して処理のためにpayLoadを渡すために、マネージドBean参照を使用してコンテキスト・イベント・リクエストをディスパッチします。バッキングBeanスコープで定義されたマネージドbeanには、Beanが依存ユーザー・インタフェースをリフレッシュできるようにするJSFコンポーネント参照がある場合があります。
このアプローチが機能するためには、次の条件が満たされている必要があります。
イベント・レシーバ・メソッドは、メッセージを処理するメソッドの引数としてpayLoadを渡す必要があります。
イベント・レシーバ・メソッドには、サブスクライバ・リージョン・タスク・フローに関連付けられているマネージドBeanにオブジェクト参照を渡すために使用される第2引数が必要です。
参照として渡されるマネージドBeanには、イベント・メッセージを入力引数として受け入れる一般に既知のパブリック・メソッドが含まれている必要があります。このメソッドはイベントを処理します。
始める前に:
コンテキスト・イベントの作成時に使用可能な各オプションについて理解しておくと役立ちます。詳細は、40.5項「プレーンJavaオブジェクト(POJO)を使用したコンテキスト・イベントの作成」を参照してください。
また、コンテキスト・イベントで使用可能な各機能についても理解しておくと役立ちます。詳細は、40.1.2項「コンテキスト・イベントの追加機能」を参照してください。
汎用イベント・レシーバおよびマネージドBeanイベント・ハンドラを作成する手順:
POJOデータ・コントロールを作成します。
POJOデータ・コントローラが「データ・コントロール」パネルに表示されます。
データ・コントロールの詳細は、『Oracle ADFデータ・コントロールによるアプリケーションの開発』のBeanデータ・コントロールの作成と構成に関する項を参照してください。
2つの引数を定義するイベント・ハンドラ・メソッドで、イベント・レシーバ・クラス(POJOデータ・コントロールで公開)を作成します。
最初の引数は、コンテキスト・イベントで提供されるpayLoad用です。2番目の引数は、コンテキスト・イベント・ハンドラ・インタフェースを実装しているマネージドBeanへのコールバック・ハンドラ参照です。
ContextualEventHandler
インタフェースを実装するバッキングBeanスコープでマネージドBeanを作成します。
ContextualEventHandler
インタフェースの実装には、handleEvent()
など、マネージドBeanに制御を渡すために汎用コンテキスト・イベント・レシーバによってコールされるコールバック・メソッドの定義が含まれます。
イベントを受信するタスク・フロー内のビューのページ定義ファイルにメソッド・バインディングを作成します。
「アプリケーション」ウィンドウで、イベント・マップを含めるページ定義ファイルをダブルクリックします。
概要エディタの「バインディングと実行可能ファイル」タブをクリックし、「バインディング」セクションの「追加」アイコンをクリックします。
「アイテムの挿入」ダイアログで、「一般バインディング」カテゴリのmethodActionを選択し、イベント・レシーバ・メソッドを公開するPOJOデータ・コントロールを選択します。
EL式ビルダーを使用して、ContextualEventHandler
引数に対して作成されたマネージドBeanを参照します。payLoad
引数はコンテキスト・イベント・マッパーによって提供されるため、空白のままにします。
メソッド・バインディングが宣言された同じページ定義ファイルに定義することで、コンテキスト・イベントをサブスクライブします。
コンテキスト・イベントのサブスクライブの一般的な手順は、40.2.2項「コンテキスト・イベントをサブスクライブおよび使用する方法」の手順7から手順8に従います。
これは、ビューのコンテキストで処理されるコンテキスト・イベント・ペイロードをイベントへの応答として変更するために、構成されたマネージドBeanに対してメソッドを呼び出す汎用的で再利用可能なコンテキスト・イベント・ハンドラの実装です。
マネージドBeanからアクセスできるアクションとメソッド・バインディングはすべて、JavaScriptから呼び出すことができます。ADF Facesは、af:serverListener
操作コンポーネントを提供します。これは、クライアント側JavaScriptからマネージドBeanメソッドを呼び出すために使用できます。参照されたマネージドBeanメソッドを使用してこのコンポーネントを呼び出すには、BindingContext
オブジェクトを使用して、現在のBindingContainer
を調べ、OperationBinding
またはJUEventBinding
バインディングにアクセスします。また、af:serverListener
コンポーネントを使用して、ブラウザ・クライアントからマネージドBeanメソッドにメッセージpayload
を送信することもできます。
ほとんどの状況では、40.3項「コンテキスト・イベントの手動作成」の説明に従って、イベント・マップ・エディタを使用してイベント・マップを作成できます。しかし、プロデューサ・イベントが埋込み動的リージョン内のページから発生する場合などの状況では、設計時にイベント・マップ・エディタを使用してイベント・マップ作成に必要な情報を取得できません。
始める前に:
コンテキスト・イベントの作成時に使用可能な各オプションについて理解しておくと役立ちます。詳細は、40.7項「イベント・マップの手動作成」を参照してください。
また、コンテキスト・イベントで使用可能な各機能についても理解しておくと役立ちます。詳細は、40.1.2項「コンテキスト・イベントの追加機能」を参照してください。
イベント・マップを手動で作成するには:
「アプリケーション」ウィンドウで、コンシューマ用のバインディングを含むページ定義ファイルをダブルクリックします。
「構造」ウィンドウで、ページ定義を表す最上位のノードを右クリックし、「pagedef名の中に挿入」→eventMapを選択します。
「構造」ウィンドウで、「eventMap」ノードを選択して右クリックし、「eventMapの中に挿入」→「event」を選択します。
「eventの挿入」ダイアログで、イベント名を入力して「OK」をクリックします。
手順3から4を繰り返して、さらにイベントを追加します。
「event」ノードを選択して右クリックし、「eventの中に挿入」→「プロデューサ」を選択します。
「プロデューサの挿入」ダイアログで、このイベントを生成するバインディングの名前を入力して、「OK」をクリックします。
イベント・プロデューサを持つリージョンの名前を入力することもできます。この場合、このタグの下に指定されたコンシューマはすべて、このイベントを使用できます。また、"*"を入力して、このタグの下のコンシューマすべてが使用できることを示すこともできます。
「プロデューサ」ノードを選択して右クリックし、「プロデューサの中に挿入」→「コンシューマ」を選択します。
「コンシューマの挿入」ダイアログで、このイベントを使用するハンドラの名前を入力して、「OK」をクリックします。
手順7から8を繰り返して、さらにコンシューマを追加します。
渡すパラメータがある場合は、パラメータ名および値を追加します。
「コンシューマ」ノードを選択して右クリックし、「コンシューマの中に挿入」→「parameters」を選択します。
「parameters」ノードを選択して右クリックし、「parametersの中に挿入」→「parameters」を選択します。
「パラメータの挿入」ダイアログで、パラメータ名およびパラメータ値を入力して、「OK」をクリックします。値はEL式でもかまいません。
さらにパラメータを追加するには、この手順を繰り返します。
デフォルトでは、コンテキスト・イベント・フレームワークはEventDispatcherImpl
を使用して、リージョンを横断するイベントをディスパッチします。デフォルトのイベント・ディスパッチャをオーバーライドするカスタム動作を提供して、カスタム・イベント・ディスパッチャを作成することができます。デフォルトのディスパッチャをオーバーライドするには、作成したカスタム・イベント・ディスパッチャをDatabindings.cpx
ファイルに登録する必要があります。
始める前に:
コンテキスト・イベントの作成時に使用可能な各オプションについて理解しておくと役立ちます。詳細は、40.8項「カスタム・ディスパッチャの登録」を参照してください。
また、コンテキスト・イベントで使用可能な各機能についても理解しておくと役立ちます。詳細は、40.1.2項「コンテキスト・イベントの追加機能」を参照してください。
カスタム・イベント・ディスパッチャを登録するには:
EventDispatcher
クラスに基づいて、カスタム・イベント・ディスパッチャのJavaクラスを作成します。
次の形式の完全修飾名を使って、カスタム・イベント・ディスパッチャをDatabindings.cpx
ファイルに登録します。
EventDispatcher="package_name
.CustomEventDispatcher_name
"
例40-13は、パッケージNewPackage
に作成されたNewCustomEventDispatcher
というカスタム・イベント・ディスパッチャのコードを示します。
プロデューサのページ定義にイベントを作成します。詳細は、40.2項「コンテキスト・イベントの宣言的な作成」または40.3項「コンテキスト・イベントの手動作成」を参照してください。
コンシューマが動的リージョンにある場合は、コンシューマ・リージョンにイベント・マップを作成します。コンシューマが動的リージョンにはない場合でも、プロデューサ・リージョンとコンシューマ・リージョンの両方が入っている親ページにイベント・マップを指定できます。詳細は、40.7項「イベント・マップの手動作成」を参照してください。