46 コンテキスト・イベントの使用
この章の内容は次のとおりです。
コンテキスト・イベントの作成について
Oracle ADFのコンテキスト・イベント機能は、パラメータを渡してページおよびリージョン間で情報を共有するための強力なメカニズムを備えています。コンテキスト・イベントを作成するには、マネージドBean、プレーンJavaオブジェクトおよび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チャートが含まれています。図46-1に、製品リージョンと在庫リージョンを表示する「Inventory Control」タブを示します。
図46-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
ファイルに登録されます。
<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はコンシューマのページ定義ファイルに作成されます。
<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()
ハンドラを追加します。
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
参照はかわりにオブジェクトを返します。次の例は、入力コンポーネントと関連付けられている属性値バインディング内部の値の変更イベントを示しています。このページでユーザーがLAST_NAME
の値を変更すると、イベントvalueChangeEvent
がディスパッチされます。
<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
のインスタンスであり、新規の値、古い値、プロデューサ・イテレータ、バインディング・コンテナおよびソースへのアクセスを提供します。前述のeventMap
の例は、範囲バインディングに関連付けられた通貨変更イベントのイベント・マップを示しています。
値属性バインディングおよび範囲バインディングのコンテキスト・イベントは、ナビゲーションの変化によってトリガーすることもできます。たとえば、ツリー表バインディングの内部にイベントを作成した場合、ユーザーがページでこのツリーの別ノードを選択したときに、このイベントがディスパッチされます。
「プロパティ」ウィンドウの「動作」セクションの下にある「コンテキスト・イベント」セクションを使用すると、コンテキスト・イベントを作成および公開できます。図46-2に示すように、「コンテキスト・イベント」パネルは、ページから適切なコンポーネントまたはリージョンを選択した場合にのみ表示されます。
図46-2 「プロパティ」ウィンドウの「コンテキスト・イベント」パネル
コンテキスト・イベントのサブスクライブには、ページ定義ファイルの「コンテキスト・イベント」タブの「サブスクライバ」セクションにある概要エディタを使用します(図46-3を参照)
コンシューミング・リージョンのページ定義のeventMap
内で、refresh="false"
をコンシューマ要素に追加して、コンテキスト・イベントの使用時に自動リージョン・リフレッシュをオフにすることができます。refresh
をfalse
に設定すると、イベント・コンシューミング・リージョンのリフレッシュを担当する場合に役に立ちます。refresh属性のデフォルトはtrue
です。加えて、コンシューミング・リージョンのページ定義のeventMap
の内部にあるコンシューマ要素に存在するhandleCondition
属性のELバインディングを使用して、コンテキスト・イベントの特定のインスタンスでサブスクライバ・リージョンをオフにすることもできます。次のページ定義ファイル・ソースおよび「プロパティ」画面は、コンシューミング・リージョンのページ定義のmethodAction
バインディングおよびeventMap
を示し、ここでは、region
およびhandleCondition
属性を追加することで、コンシューミング・リージョンのコンテキスト・イベント・レスポンスが制御されています。
コンテキスト・イベントのユースケースと例
リージョンと親ページ間の通信パターンには、親対リージョン、リージョン対親、リージョン対リージョンの3種類があります。コンテキスト・イベント・フレームワークは、これら3つのシナリオすべてに対応する、非常に強力な通信実装です。コンテキスト・イベントでは、リージョンが入力パラメータを使用するために、リージョンをリフレッシュする必要はありません。
ADFリージョン間で通信を行うには、コンテキスト・イベントを使用する必要があります。ADFタスク・フロー・パラメータを使用してリージョン間の通信もできますが、この場合、リージョン間に直接的な依存性が生じてしまう可能性があります。静的なリージョンに対しては、ADFタスク・フロー・パラメータの使用が適切な場合もありますが、コンテキスト・イベントを使用すると、リージョン間の独立した通信を実装できます。
たとえば、従業員情報を入力するためのフォームを保持するリージョンがページに含まれるとします。ユーザーが従業員IDを更新し、送信ボタンを押すと、値変更コンテキスト・イベントが発生し、従業員ID値がpayLoadとして渡されます。同じページ上の別のリージョンがこのイベントをサブスクライブして使用することで、コンテキスト・イベントとともに渡されたpayLoadの情報に基づき、選択された従業員に対する部署情報を表示できます。
コンテキスト・イベントのその他の機能
コンテキスト・イベントの処理を開始する前に、その他のADF機能について理解しておいてください。次に、関連する他の機能へのリンクを示します。
-
ADFタスク・フロー・パラメータを使用して、ADFリージョン間で通信を行うこともできます。タスク・フローとリージョンの使用の詳細は、「リージョンとしてのタスク・フローの使用」を参照してください。
コンテキスト・イベントの宣言的な作成
Oracle ADFのコンテキスト・イベントには、パブリッシャ・イベント(プロデューサ)とハンドラ・イベント(コンシューマ)の2つの部分があります。コンテキスト・イベントの宣言的な作成のプロセスでは、様々な手順に従ってイベントを公開、サブスクライブおよび使用します。
コンテキスト・イベントを作成するには、まず、メソッド・アクション、アクション、値属性、またはリスト・バインディングに基づいて、プロデューサにイベントを作成し、公開します。コンシューマで、このイベントをサブスクライブし、これを処理するためのハンドラを作成します。
通常、タスク・フローおよびビュー・アクティビティを含むリージョンを持つ親ページを作成します。リージョンの1つには、もう1つのリージョンのコンシューマ・イベント・ハンドラのために公開されるコンテキスト・イベントを作成します。タスク・フローとリージョンの使用の詳細は、「リージョンとしてのタスク・フローの使用」を参照してください。
ノート:
コードから(マネージドBeanの内部などから)アクション・コンテキスト・イベントを公開することもできます。EventDispatcher
のインスタンスを戻すgetBindingContainer().getEventDispatcher
を使用します。EventDispatcher
には、コンテキスト・イベントをプログラミングによって発生させるために使用できるパブリックAPIがあります。
コンテキスト・イベントの公開方法
「プロパティ」ウィンドウを使用して、コンテキスト・イベントを生成するページにコンテキスト・イベントを作成します。つまり、プロデューサのページが、コンテキスト・イベントを生成するページになります。イベントはローカルまたはリモート・コンシューマに向けて公開できます。デフォルトで、すべてのイベントはローカル・コンシューマに公開されます。たとえば、あるページのボタンをクリックすると、別のコンポーネントで利用されるコンテキスト・イベントがトリガーされるとします。このボタンを含むページが、プロデューサのページになります。
始める前に:
コンテキスト・イベントの作成時に使用可能な各オプションについて理解しておくと役立ちます。「コンテキスト・イベントの宣言的な作成」を参照してください。
また、コンテキスト・イベントで使用可能な各機能についても理解しておくと役立ちます。「コンテキスト・イベントのその他の機能」を参照してください。
次のタスクを完了する必要があります。
- コンテクスト・イベントを発生させるために使用するコンポーネントのタイプを決定します。メソッド・アクション・バインディングの使用を計画している場合は、ページにドロップするメソッドをあらかじめ作成しておく必要があります。
コンテキスト・イベントを作成するには:
-
コンテキスト・イベントを公開するページで、「データ・コントロール」パネルからコンポーネントをドラッグし、そのページにドロップします。
このコンポーネントで、イベントをトリガーすることになります。これには、メソッド・アクション、アクション、値属性またはリストのバインディング・イベントが必要です。
-
「プロパティ」ウィンドウで、「動作」セクションを開きます。
-
「イベントの発行」セクションで「追加」アイコンをクリックします。
-
コンテキスト・イベントの公開ダイアログで:
-
「新規イベントの作成」を選択します。
-
イベントの名前を入力します。
-
表、ツリーまたはツリー表のコンポーネントを使用している場合は、「ノード」フィールドが表示されます。このフィールドには、変更イベントの発生時にイベントを公開するノードを入力します。
-
ペイロード・データをコンシューマに渡す場合は、「次からカスタム値を渡す」を選択します。
-
payloadデータを渡す場合は、ドロップダウン・リストからデータ型を選択します。通常、このパラメータは、{$payLoad}になります。
たとえば、プロデューサ・ページからコンシューマ・ページに属性値を渡す場合は、「ページ・データ」を選択して、ツリー構造から目的の属性を選択します。
-
「呼出し条件」タブにEL式を入力して、条件付きでイベントを発生させることができます。
たとえば、式
${bindings.LAST_NAME.inputValue == 'KING'}
を入力すると、顧客の姓が「KING」である場合のみ、イベントが発生します。 -
「OK」をクリックします。
イベントはこのページに作成されますが、コンポーネント・バインディングと関連付けるまで公開できません。
図46-5 コンテキスト・イベントの公開
-
-
デフォルトで、すべてのイベントはローカル・リージョンにディスパッチされます。イベントをリモート・リージョンにディスパッチするには:
-
イベントを生成するページのページ定義ファイルの「ソース」ビューで、イベントを選択して「プロパティ」ウィンドウでそのイベントのプロパティを表示します。
-
dispatchMode
属性をremoteに設定します。ノート:
リモート・リージョンからリモート・イベントが発生したときにdispatchMode
属性がremote値に設定されていない場合、java.io.NotSerializableException
という例外が発生する場合があります。このシナリオでは、dispatchMode
属性をlocal値に設定しないことをお薦めします。 -
customPayLoad
属性に、シリアライズ可能オブジェクトを参照するEL式を記述します。 -
customPayLoadType
属性で、オブジェクトのカスタム・ペイロードのタイプを指定します。
-
コンテキスト・イベントをサブスクライブおよび使用する方法
コンテキスト・イベントにサブスクライブするには、ページ定義ファイルの概要エディタを使用します。概要エディタには、現在のリージョンと、その子のリージョンが表示されます。コンテキスト・イベントにサブスクライブできるリージョンのみが表示されます。
始める前に:
コンテキスト・イベントの作成時に使用可能な各オプションについて理解しておくと役立ちます。詳細は、「コンテキスト・イベントの宣言的な作成」を参照してください。
また、コンテキスト・イベントで使用可能な各機能についても理解しておくと役立ちます。詳細は、「コンテキスト・イベントのその他の機能」を参照してください。
次のタスクを完了する必要があります。
- 「コンテキスト・イベントの公開方法」の説明に従い、ページ定義ファイル内にコンテキスト・イベントを作成します。
イベントをサブスクライブし、使用するには:
-
イベントとそのペイロード・データを処理するハンドラを作成します。
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」をクリックします。
図46-6 コンテキスト・イベントのサブスクライブ
ノート:
「構造」ウィンドウでページ定義を右クリックし、「イベント・マップの編集」を選択し、イベント・マップを編集することができます。ページ定義ファイルまたは「プロパティ」ウィンドウで、イベントの属性を編集することもできます。
-
コンテキスト・イベントの作成時の処理
作成者のイベントを作成すると、JDeveloperはページ定義ファイルにevents
要素を追加します。各イベント名が子として追加されます。次のプロデューサのイベント定義の例は、通貨変更イベントとしてプロデューサのページ定義ファイル内に定義されたproductSelected
イベントを示しています。
<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>
コンシューマのページ定義ファイルには、イベントに応答するメソッド・アクション・バインディングが作成されます。次のメソッド・アクションの定義の例は、showInventoryPageDef
ページ定義ファイル内に定義されたメソッド・アクション・バインディングを示しています。
<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は対応するページ定義ファイルにイベント・マップのエントリを作成します。次の例は、showproductstaskflowdefinition1
リージョンからproductinventorytaskflowdefinition1
リージョンにproductSelected
イベントをマップする、showInventoryPageDef
ページ定義ファイルのイベント・マップを示しています。また、showInventoryPageDef
ページ定義ファイルで定義されているpopulateInventoryForProduct
ハンドラ・メソッド・バインディングもマップしています。このハンドラは、payLoad情報(productID
が含まれる)を処理してDVTコンポーネントに渡すため、このコンポーネントは、その製品の倉庫内在庫を問合せできるようになります。
<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>
dispatchMode
の値をremoteに設定すると、ページ定義ファイル内でJDeveloperがevent
要素に属性dispatchMode
を追加します。CustomPayLoadType
は渡されるペイロードのタイプです。getCustomPayLoad()
が文字列を返す場合は文字列です。次の例はイベント要素を示しています。このイベント要素には、remoteに設定されたdispatchMode
属性と、リモート・コンシューマに渡すカスタム・ペイロードを指定する属性が含まれています。
<methodAction id="eventProducer" RequiresUpdateModel="true" Action="invokeMethod" MethodName="eventProducer" IsViewObjectMethod="false" DataControl="Class1" InstanceName="bindings.eventProducer.dataControl.dataProvider" ReturnName="data.Class1.methodResults.eventProducer_eventProducer_dataControl_dataProvider_eventProducer_result"> <events xmlns="http://xmlns.oracle.com/adfm/contextualEvent"> <event name="teste" eventType="Action Event" dispatchMode="remote" customPayloadType="java.lang.String" customPayLoad="#{testBean.customPayLoad}"/> </events> </methodAction>
コンテキスト・イベント・ディスパッチの制御方法
アプリケーション・レベル、またはページ・レベルで、子リージョンへのコンテキスト・イベントのディスパッチを制御できます。
始める前に:
コンテキスト・イベントの作成時に使用可能な各オプションについて理解しておくと役立ちます。詳細は、「コンテキスト・イベントの宣言的な作成」を参照してください。
また、コンテキスト・イベントで使用可能な各機能についても理解しておくと役立ちます。詳細は、「コンテキスト・イベントのその他の機能」を参照してください。
イベントのディスパッチを無効化するには:
実行時に行われる処理: コンテキスト・イベント
イベント・プロデューサとコンシューマの両方が同じページ定義ファイルに定義されている場合、対応するページの呼び出しおよびバインディング・コンテナの作成後、次の場合にイベントが発生します。
-
対応するメソッドまたはアクション・バインディングが実行される
-
値バインディングが正常に設定される
-
レンジ・バインディングの現行性が正常に設定される
メソッド・バインディングの場合、メソッド実行の結果がイベントのペイロードを形成し、イベントがキューイングされます。JSFライフサイクルのアプリケーションの起動フェーズで、キューイングされたすべてのイベントがディスパッチされます。バインディング・コンテナに関連付けられたイベント・ディスパッチャは、そのイベントに関連するコンシューマをイベント・マップで確認し、イベントをコンシューマに渡します(イベント・マップは同じページ定義ファイルの一部であるため、バインディング・コンテナにも含まれます)。
プロデューサとコンシューマが異なるリージョンに存在する場合、イベントは最初に同じコンテナ内の任意のコンシューマにディスパッチされ、次にイベント伝播が親バインディング・コンテナに委任されます。この処理は、親または最上位のバインディング・コンテナに達するまで続きます。最上位バインディング・コンテナに達した後、プロデューサがワイルドカード(*
)に設定されているページでリージョンを保持する子バインディング・コンテナに、イベントが再度ディスパッチされます。
リモート・リージョンからリモート・イベントが発生したときにdataControlを使用してデータ値を渡す場合、データ値をリモート・リージョンに正しく提供するにはdispatchMode
属性をremote値に設定する必要があります。そうしないと、java.io.NotSerializableException
という例外が発生する場合があります。このシナリオでは、dispatchMode
属性をlocal値に設定しないことをお薦めします。
コンテキスト・イベントの手動作成
Oracle ADFのコンテキスト・イベントには、パブリッシャ・イベント(プロデューサ)とハンドラ・イベント(コンシューマ)の2つの部分があります。コンテキスト・イベントを手動で作成するプロセスでは、詳細な手順に従ってイベントを公開および使用します。
コンテキスト・イベントの作成では、最初に作成者にイベントを作成します。続いてイベントのコンシューマを定義し、プロデューサとコンシューマをマッピングします。
コンテキスト・イベントの手動作成方法
始める前に:
コンテキスト・イベントの作成時に使用可能な各オプションについて理解しておくと役立ちます。詳細は、「コンテキスト・イベントの手動作成」を参照してください。
また、コンテキスト・イベントで使用可能な各機能についても理解しておくと役立ちます。詳細は、「コンテキスト・イベントのその他の機能」を参照してください。
次のタスクを完了する必要があります。
- メソッド・バインディング、アクション・バインディング、値属性バインディングまたはリスト・バインディングを持つコンテキスト・イベントをプロデューサ・ページ上に作成します。
コンテキスト・イベントを作成するには:
-
「アプリケーション」ウィンドウで、イベントのプロデューサ用のバインディングを含むページ定義ファイルをダブルクリックします。
作成者には、イベントの発行に使用される関連付けられたバインディングが必要です。たとえば、メソッドまたは操作が作成者になる場合、イベントは関連アクション・バインディングまたはメソッド・アクション・バインディングに含まれます。
-
「構造」ウィンドウで、プロデューサのバインディングを右クリックし、「バインディング名の中に挿入」→「event」または「バインディング名の中に挿入」→「コンテキスト・イベント」→「event」を選択します。
-
「構造」ウィンドウで、たった今作成されたevents要素を右クリックし、「eventsの内部に挿入」→「event」を選択します。
-
「eventの挿入」ダイアログで、「名前」フィールドにイベント名を入力し、「終了」をクリックします。
これで、イベントが作成されます。デフォルトでは、関連するメソッドまたは操作の戻り値はすべて、イベントのペイロードとして取得され、ELでアクセス可能な変数
${data.payLoad}
に格納されます。次に、イベントをコンシューマにマッピングし、コンシューマに渡す必要があるペイロードを構成する必要があります。 -
「アプリケーション」ウィンドウで、コンシューマ用のバインディングを含むページ定義ファイルをダブルクリックします。
このページが表すバインディング・コンテナは、含まれるバインディング・コンテナすべてを含む現在のスコープ(タスク・フロー・リージョンなど)からイベントへのアクセスを提供します。リージョンまたは他のネストされたコンテナがイベントを認識する必要がある場合、イベント・マップは使用リージョン内のページのページ定義に存在する必要があります。
-
「構造」ウィンドウで、ページ定義を表す最上位のノードを右クリックし、「イベント・マップの編集」を選択します。
ノート:
プロデューサ・イベントが埋込み動的リージョン内のページから発生する場合、イベント・マップ・エディタを使用してイベント・マップを編集できないことがあります。イベント・マップを手動で作成するには、ページ定義ファイルを編集するか、「コンテキスト・イベントの手動作成」で説明している「内部に挿入」のステップを使用します。
-
イベント・マップ・エディタで、「追加」アイコンをクリックして、イベント・エントリを追加します。
-
「新規EventMapエントリの追加」ダイアログ・ボックスで、次の操作を行います。
-
作成者ドロップダウン・メニューを使用して作成者を選択します。
-
「イベント名」ドロップダウン・メニューを使用してイベントを選択します。
-
使用者ドロップダウン・メニューを使用して使用者を選択します。これは、イベントを使用する実際のメソッドになります。
-
使用するメソッドまたは操作にパラメータが必要な場合は、「追加」アイコンをクリックします。
「パラメータ名」フィールドに、メソッドに必要なパラメータの名前を入力します。「パラメータ値」フィールドに値を入力します。これがイベントからのペイロードの場合は、
${data.payLoad}
式を使用すると、この値にアクセスできます。ペイロードに複数のパラメータが含まれ、それらすべてを必要とする場合以外は、省略記号ボタンを使用して「式ビルダー」ダイアログを開きます。このダイアログを使用して、「ペイロード」ノードの下の特定のパラメータを選択できます。また、「パラメータ」省略記号ボタンをクリックして、選択ダイアログを開くこともできます。
-
「OK」をクリックします。
-
-
イベント・マップ・エディタで、「OK」をクリックします。
マネージドBeanを使用したコンテキスト・イベントの作成
Oracle ADFでは、マネージドBeanの内部など、コードからのアクション・コンテキスト・イベントの公開がサポートされます。マネージドBeanを使用してコンテキスト・イベントを動的に作成および操作することもできます。
マネージドBeanを使用したコンテキスト・イベントの作成方法
始める前に:
コンテキスト・イベントの作成時に使用可能な各オプションについて理解しておくと役立ちます。詳細は、「マネージドBeanを使用したコンテキスト・イベントの作成」を参照してください。
また、コンテキスト・イベントで使用可能な各機能についても理解しておくと役立ちます。詳細は、「コンテキスト・イベントのその他の機能」を参照してください。
マネージドBeanを使用してコンテキスト・イベントを作成するには:
マネージドBeanを使用したコンテキスト・イベントの作成時の処理
次に示すとおり、このページ定義ファイルには、プロデューサのメソッド・アクション・バインディング、コンシューマおよびイベント・マップが含まれます。
<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>
マネージドBeanを使用したコンテキスト・イベントの動的作成および操作の方法
始める前に:
コンテキスト・イベントの作成時に使用可能な各オプションについて理解しておくと役立ちます。詳細は、「マネージドBeanを使用したコンテキスト・イベントの作成」を参照してください。
また、コンテキスト・イベントで使用可能な各機能についても理解しておくと役立ちます。詳細は、「コンテキスト・イベントのその他の機能」を参照してください。
マネージドBeanを使用してコンテキスト・イベントを作成および操作するには:
プレーンJavaオブジェクト(POJO)を使用したコンテキスト・イベントの作成
Oracle ADFは、任意の数のパラメータを受け取ることができるバインド・タスク・フローを提供し、単純なフィードバックをコール元に結果の形式で提供できます。タスク・フローがJavaオブジェクトを返すことのできる戻りパラメータもあります。
リージョンに埋め込まれているバインドされたタスク・フローには、コンテキスト・イベントの潜在的なコンシューマとして公開する必要のある複数のビューがある場合があります。各ビューのプレーンJavaオブジェクト(POJO)、データ・コントロールおよびイベント・ハンドラを作成するかわりに、単一のPOJOと単一のデータ・コントロールを作成して、タスク・フロー内のすべてのビューのイベントを処理できます。
このアプローチでは、イベント・レシーバ・メソッドは、handleEvent
メソッドを呼び出して処理のためにpayLoadを渡すために、マネージドBean参照を使用してコンテキスト・イベント・リクエストをディスパッチします。バッキングBeanスコープで定義されたマネージドbeanには、Beanが依存ユーザー・インタフェースをリフレッシュできるようにするJSFコンポーネント参照がある場合があります。
このアプローチが機能するためには、次の条件が満たされている必要があります。
-
イベント・レシーバ・メソッドは、メッセージを処理するメソッドの引数としてpayLoadを渡す必要があります。
-
イベント・レシーバ・メソッドには、サブスクライバ・リージョン・タスク・フローに関連付けられているマネージドBeanにオブジェクト参照を渡すために使用される第2引数が必要です。
-
参照として渡されるマネージドBeanには、イベント・メッセージを入力引数として受け入れる一般に既知のパブリック・メソッドが含まれている必要があります。このメソッドはイベントを処理します。
タスク・フローに対して汎用コールバック・メッセージ・ハンドラを構成する方法
始める前に:
コンテキスト・イベントの作成時に使用可能な各オプションについて理解しておくと役立ちます。詳細は、「プレーンJavaオブジェクト(POJO)を使用したコンテキスト・イベントの作成」を参照してください。
また、コンテキスト・イベントで使用可能な各機能についても理解しておくと役立ちます。詳細は、「コンテキスト・イベントのその他の機能」を参照してください。
汎用イベント・レシーバおよびマネージドBeanイベント・ハンドラを作成するには:
-
POJOデータ・コントロールを作成します。
POJOデータ・コントローラが「データ・コントロール」パネルに表示されます。
データ・コントロールの詳細は、『Oracle ADFデータ・コントロールによるアプリケーションの開発』のBeanデータ・コントロールの作成と構成に関する項を参照してください。
-
2つの引数を定義するイベント・ハンドラ・メソッドで、イベント・レシーバ・クラス(POJOデータ・コントロールで公開)を作成します。
最初の引数は、コンテキスト・イベントで提供されるpayLoad用です。2番目の引数は、コンテキスト・イベント・ハンドラ・インタフェースを実装しているマネージドBeanへのコールバック・ハンドラ参照です。
-
ContextualEventHandler
インタフェースを実装するバッキングBeanスコープでマネージドBeanを作成します。ContextualEventHandler
インタフェースの実装には、handleEvent()
など、マネージドBeanに制御を渡すために汎用コンテキスト・イベント・レシーバによってコールされるコールバック・メソッドの定義が含まれます。 -
イベントを受信するタスク・フロー内のビューのページ定義ファイルにメソッド・バインディングを作成します。
-
「アプリケーション」ウィンドウで、イベント・マップを含めるページ定義ファイルをダブルクリックします。
-
概要エディタの「バインディングと実行可能ファイル」タブをクリックし、「バインディング」セクションの「追加」アイコンをクリックします。
-
「アイテムの挿入」ダイアログで、「一般バインディング」カテゴリのmethodActionを選択し、イベント・レシーバ・メソッドを公開するPOJOデータ・コントロールを選択します。
-
EL式ビルダーを使用して、
ContextualEventHandler
引数に対して作成されたマネージドBeanを参照します。payLoad
引数はコンテキスト・イベント・マッパーによって提供されるため、空白のままにします。
-
-
メソッド・バインディングが宣言された同じページ定義ファイルに定義することで、コンテキスト・イベントをサブスクライブします。
コンテキスト・イベントのサブスクライブの一般的なステップは、「コンテキスト・イベントをサブスクライブおよび使用する方法」のステップ7からステップ8に従います。
これは、ビューのコンテキストで処理されるコンテキスト・イベント・ペイロードをイベントへの応答として変更するために、構成されたマネージドBeanに対してメソッドを呼び出す汎用的で再利用可能なコンテキスト・イベント・ハンドラの実装です。
JavaScriptを使用したコンテキスト・イベントの作成
マネージドBeanからアクセスできるアクションとメソッド・バインディングはすべて、JavaScriptから呼び出すことができます。ADF Facesは、af:serverListener
操作コンポーネントを提供します。これは、クライアント側JavaScriptからマネージドBeanメソッドを呼び出すために使用できます。
参照されたマネージドBeanメソッドを使用してaf:serverListener
操作コンポーネントを呼び出すには、BindingContext
オブジェクトを使用して、現在のBindingContainer
を調べ、OperationBinding
またはJUEventBinding
バインディングにアクセスします。また、af:serverListener
コンポーネントを使用して、ブラウザ・クライアントからマネージドBeanメソッドにメッセージpayload
を送信することもできます。
イベント・マップの手動作成
Oracle ADFでは、イベントは、イベントを発生させるページまたはリージョン(プロデューサ)のページ定義ファイルで構成されます。イベントに基づいた操作を実行するコンシューマをプロデューサと関連付けるには、ページ定義ファイルにイベント・マップも作成します。
ほとんどの状況では、「コンテキスト・イベントの手動作成」で説明しているように、イベント・マップ・エディタを使用してイベント・マップを作成できます。しかし、プロデューサ・イベントが埋込み動的リージョン内のページから発生する場合などの状況では、設計時にイベント・マップ・エディタではイベント・マップの作成に必要な情報を取得できません。
イベント・マップの手動による作成方法
始める前に:
コンテキスト・イベントの作成時に使用可能な各オプションについて理解しておくと役立ちます。詳細は、「イベント・マップの手動作成」を参照してください。
また、コンテキスト・イベントで使用可能な各機能についても理解しておくと役立ちます。詳細は、「コンテキスト・イベントのその他の機能」を参照してください。
イベント・マップを手動で作成するには:
-
「アプリケーション」ウィンドウで、コンシューマ用のバインディングを含むページ定義ファイルをダブルクリックします。
-
「構造」ウィンドウで、ページ定義を表す最上位のノードを右クリックし、「pagedef名の中に挿入」→「eventMap」を選択します。
-
「構造」ウィンドウで、「eventMap」ノードを選択して右クリックし、「eventMapの中に挿入」→「event」を選択します。
-
「eventの挿入」ダイアログで、イベント名を入力して「OK」をクリックします。
ステップ3から4を繰り返して、さらにイベントを追加します。
-
「event」ノードを選択して右クリックし、「eventの中に挿入」→「producer」を選択します。
-
「プロデューサの挿入」ダイアログで、このイベントを生成するバインディングの名前を入力して、「OK」をクリックします。
イベント・プロデューサを持つリージョンの名前を入力することもできます。この場合、このタグの下に指定されたコンシューマはすべて、このイベントを使用できます。また、"*"を入力して、このタグの下のコンシューマすべてが使用できることを示すこともできます。
-
「producer」ノードを選択して右クリックし、「producerの中に挿入」→「consumer」を選択します。
-
「コンシューマの挿入」ダイアログで、このイベントを使用するハンドラの名前を入力して、「OK」をクリックします。
ステップ7から8を繰り返して、さらにコンシューマを追加します。
-
渡すパラメータがある場合は、パラメータ名および値を追加します。
-
「consumer」ノードを選択して右クリックし、「consumerの中に挿入」→「parameters」を選択します。
-
「parameters」ノードを選択して右クリックし、「parametersの中に挿入」→「parameter」を選択します。
-
「パラメータの挿入」ダイアログで、パラメータ名およびパラメータ値を入力して、「OK」をクリックします。値はEL式でもかまいません。
さらにパラメータを追加するには、このステップを繰り返します。
-
カスタム・ディスパッチャの登録
デフォルトでは、コンテキスト・イベント・フレームワークはEventDispatcherImpl
を使用して、リージョンを横断するイベントをディスパッチします。デフォルトのイベント・ディスパッチャをオーバーライドするカスタム動作を提供して、カスタム・イベント・ディスパッチャを作成することができます。
デフォルトのディスパッチャをオーバーライドするには、作成したカスタム・イベント・ディスパッチャをDatabindings.cpx
ファイルに登録する必要があります。
カスタム・ディスパッチャの登録方法
始める前に:
コンテキスト・イベントの作成時に使用可能な各オプションについて理解しておくと役立ちます。詳細は、「カスタム・ディスパッチャの登録」を参照してください。
また、コンテキスト・イベントで使用可能な各機能についても理解しておくと役立ちます。詳細は、「コンテキスト・イベントのその他の機能」を参照してください。
カスタム・イベント・ディスパッチャを登録するには: