この章では、マスター/ディテール関係のデータを表示する、様々なタイプのページの作成方法について説明します。
この章の内容は次のとおりです。
選択リストを使用して、関連するマスター・コレクションまたはディテール・コレクションからのキー値をコレクションに移入する方法の詳細は、19.7項「選択リストの作成」を参照してください。
ADF Business Componentsでは、マスター/ディテール関係は、ビュー・リンクによって関連付けられた2つのビュー・オブジェクト・インスタンスを示します。第5章「ビュー・オブジェクトを使用したデータの問合せ」で説明したように、ビュー・リンクは、2つのビュー・オブジェクト間の関係を示します。通常、この関係は基礎となるデータ表間の外部キー関係に基づいていますが、必ずしもそうとはかぎりません。ADFでは、ビュー・リンクを使用して、1つのビュー・オブジェクト・インスタンス(マスター・オブジェクト)の1行を別のビュー・オブジェクト・インスタンス(ディテール・オブジェクト)の1行以上の行に関連付けます。
ビュー・リンクは、マスター/ディテール関係を調整するために、ビュー・リンク・アクセッサ属性とデータ・モデルのビュー・リンク・インスタンスという2つの異なるタイプをサポートしています(詳細は、27.1.3項「ビュー・リンク・アクセッサとデータ・モデル・ビュー・リンク・インスタンス」を参照)。ただし、ADFデータ・バインディングを使用してページにマスター/ディテール・データを表示する場合は、データ・モデルのマスター/ディテールのアクティブな調整をサポートしている、データ・モデルのビュー・リンク・インスタンスのみを使用します。データ・モデルのマスター/ディテールのアクティブな調整を有効にするには、マスター・ビュー・オブジェクト・インスタンスとディテール・ビュー・オブジェクト・インスタンスの両方を適切なアプリケーション・モジュールのデータ・モデルに追加する必要があります(詳細は、5.10.4.3項「データ・モデルでアクティブなマスター/ディテール調整を有効化する方法」を参照)。たとえば、SRDemoアプリケーションには、Svr_Id属性(サービス・リクエストID)に基づくServiceRequestsビュー・オブジェクトからServiceHistoriesビュー・オブジェクトへのビュー・リンクがあります。ここでは、マスター・ビュー・オブジェクトとディテール・ビュー・オブジェクトの両方がアプリケーション・モジュールのデータ・モデルに追加されています。このため、マスター・ビュー・オブジェクト・インスタンスの現在の行を変更すると、ディテール・ビュー・オブジェクト・インスタンスの行セットがリフレッシュされて現在のマスターの詳細が含まれるようになります。
オブジェクトがマスター/ディテール関係にある場合は、両方のオブジェクトのデータを同時に表示するページを宣言的に作成できます。たとえば、SRDemoアプリケーションには、ページ最上部のフォームにサービス・リクエストを表示し、ページ最下部の表に関連するサービス履歴を表示するページが含まれています。このような表示ができるのは、サービス・リクエストとサービス履歴のオブジェクトがマスター/ディテール関係にあるためです。この例の場合は、サービス・リクエストがマスター・オブジェクトで、サービス履歴がディテール・オブジェクトです。ADFイテレータは、選択されたマスター・データ・オブジェクトに対して表示されるディテール・データ・オブジェクトの同期化を自動的に管理します。
この章では次の内容について説明します。
ADFでのマスター/ディテール関係
データ・コントロール・パレットでのマスター/ディテール・オブジェクトの識別方法
表、フォーム、ツリー、ツリー表およびインライン表でのマスター/ディテール・オブジェクトの表示方法
ナビゲーション・コンポーネントで接続された様々なページでのマスター/ディテール・オブジェクトの表示方法
ADFイテレータによるマスター・オブジェクトとディテール・オブジェクトの同時実行性の管理
データ・コントロール・パレットでのマスター/ディテールUIコンポーネントの作成時に作成されるバインディング・オブジェクト
JDeveloperでは、データ・コントロール・パレットを使用して、マスター/ディテール・データを表示するページを宣言的に作成できます。データ・コントロール・パレットでは、マスター/ディテール関連オブジェクトが階層に表示されます。この階層は、アプリケーション・モジュールのデータ・モデルで定義した階層がミラー化されたもので、ディテール・オブジェクトはマスター・オブジェクトの子として表示されます。データ・モデルへのマスター/ディテール・オブジェクトの追加に関する詳細は、5.10.4.3項「データ・モデルでアクティブなマスター/ディテール調整を有効化する方法」を参照してください。
図15-1は、SRDemoアプリケーションのデータ・コントロール・パレットに表示された2つのマスター/ディテール関連コレクションを示しています。ServiceRequestsコレクションはServiceRequestsビュー・オブジェクトのインスタンスで、ServiceRequestsコレクションの子として表示されているServiceHistoriesコレクションはServiceHistoriesビュー・オブジェクトのインスタンスです。データ・コントロール・パレット上のマスター/ディテール階層には、図15-2のように、SRServiceアプリケーション・モジュールのデータ・モデルに定義されている階層が反映されます。この階層は、ServiceRequestsビュー・オブジェクトからServiceHistoriesビュー・オブジェクトへのビュー・リンクを作成することによって確立されました。次に、図15-2のように、この結果のディテール・ビュー・オブジェクトのインスタンスであるServiceHistories via ServicesHistoriesForServiceRequest1がアプリケーション・モジュールのデータ・モデルに追加され、ServiceHistoriesという名前が付けられました。
|
ヒント: データ・コントロール・パレットに表示されるマスター/ディテール階層には、関係のカーディナリティ(1対多、1対1、多対多など)は反映されません。階層には、別のコレクション(ディテール)から1つ以上のオブジェクトを取得するために使用されているコレクション(マスター)が簡潔に示されます。 |
SRDemoアプリケーションでは、ServiceRequestsビュー・オブジェクトとServiceHistoriesビュー・オブジェクト間のビュー・リンクは一方向的な関係です。ビュー・リンクが双方向的で、マスター・ビュー・オブジェクトとディテール・ビュー・オブジェクトの両セットがアプリケーション・モジュールのデータ・モデルに追加された場合、データ・コントロール・パレットには、ServiceHistoriesコレクションもServiceRequestsコレクションと同じノード・レベルで表示され、ServiceRequestsコレクションのディテール・インスタンスもServiceHistoriesコレクションの子として表示されます。
マスター/ディテール・オブジェクトを表示するページを作成する際には、目的にあわせて、マスターになるオブジェクトとディテールになるオブジェクトを正しく識別してください。これを怠ると、目的のデータをページに表示できません。
たとえば、1人のユーザーおよびそのユーザーが割り当てられたすべての関連する専門技術領域を表示する場合は、Userをマスター・オブジェクトにします。逆に、1つの専門技術領域およびその専門技術領域に割り当てられたすべてのユーザーを表示する場合は、expertiseAreaをマスター・オブジェクトにします。ページに表示されるディテール・オブジェクトは、どちらのオブジェクトがマスターであるかによって異なります。
|
ヒント: デフォルトでは、ビュー・リンクの作成ウィザードを使用してビュー・リンクを定義する場合、ソース・ビュー・オブジェクトがマスターになり、リンク先ビュー・オブジェクトがディテールになります。ただし、ソース・ビュー・オブジェクトとリンク先ビュー・オブジェクトの両方でアクセッサを生成する場合、マスター/ディテール関係は双方向になります。双方向のビュー・リンクによって確立されたマスター/ディテール・ビュー・オブジェクトの両セットをアプリケーション・モジュールのデータ・モデルに追加すると、ビュー・オブジェクトの両セットのインスタンスはデータ・コントロール・パレットで独立して表示されます。 |
データ・コントロール・パレットに表示されるアイコンの詳細は、12.2.1項「データ・コントロール・パレットの各項目の理解」を参照してください。
JDeveloperのデータ・コントロール・パレットを使用すると、マスター/ディテールの参照ページを単一の宣言的アクションで作成できます。追加のコードを記述する必要がなく、ナビゲーションも組み込まれます。データ・コントロール・パレットでは、事前作成済のマスター/ディテール・ウィジェットが提供されます。これにより、同じページ上でマスターとディテールの両オブジェクトを読取り専用の表およびフォームの任意の組合せとして表示できます。そのために必要な操作は、ディテール・コレクションをページ上にドロップして、使用するウィジェットのタイプを選択するのみです。
データ・コントロール・パレットで使用できる事前作成済のマスター/ディテール・ウィジェットには、コレクション内のデータ・オブジェクト全体をスクロールするためのレンジ・ナビゲーションが含まれます。事前作成済のマスター/ディテール・ウィジェットに用意されている表には、選択ファセットおよび「Submit」コマンド・ボタンが含まれます。デフォルトでは、マスター・オブジェクトとディテール・オブジェクトのすべての属性が、テキスト・フィールド(フォームの場合)または列(表の場合)としてマスター/ディテール・ウィジェットに含まれます。テキスト・フィールドまたは列をページから削除すると、不要な属性を削除できます。
|
ヒント: 事前作成済のマスター/ディテール・ウィジェットを使用しない場合、マスター・オブジェクトとディテール・オブジェクトを1つのページまたは個別の各ページに表およびフォームとして別々にドラッグ・アンド・ドロップできます。個々のフォームおよび表の作成の詳細は、第13章「基本的なページの作成」または第14章「表の追加」を参照してください。 |
マスター/ディテール・コンポーネントをページに追加する場合、ページ上のコンポーネントへのデータの公開はイテレータ・バインディングによって行われます。イテレータ・バインディングは、基礎となる行セット・イテレータにバインドします。実行時には、ディテール・ビュー・オブジェクト・インスタンスのアクティブ・データ・モデルおよび行セット・イテレータにより、現在の行が変更されたときに、ディテール・ビュー・オブジェクトの行セットが現在のマスター行の正しい行セットになるようにリフレッシュされます。
図15-3に、事前作成済のマスター/ディテール・ウィジェットの例を示します。このウィジェットでは、ページ最上部のフォームにサービス・リクエストが表示され、ページ最下部の表に関連するすべてのサービス履歴が表示されています。ユーザーがマスター・データをスクロールすると、関連するディテール・データが自動的にページに表示されます。
データ・コントロール・パレットで事前作成済のマスター/ディテール・フォームおよび表を使用すると、単一の宣言的アクションで、マスター・ウィジェットとディテール・ウィジェットの両方を1つのページ上に作成できます。マスター・データとディテール・データを個別のページに表示する方法の詳細は、15.3.4項「個別ページでのマスター/ディテールについての考慮事項」を参照してください。
事前作成済のADFマスター/ディテール・フォームおよび表を使用したマスター/ディテール・ページの作成方法:
15.2項「データ・コントロール・パレットでのマスター/ディテール・オブジェクトの識別」で説明したように、データ・コントロール・パレットでディテール・オブジェクトを特定します。
ディテール・オブジェクトをJSFページにドラッグ・アンド・ドロップします。
ポップアップ・メニューから、次のいずれかのマスター/ディテール・ウィジェットを選択します。
ADFマスター表、ディテール・フォーム: 表にマスター・オブジェクトが表示され、表の下にある読取り専用フォームにディテール・オブジェクトが表示されます。
マスター表で特定のデータ・オブジェクトを選択すると、その下にあるフォーム内に、関連する最初のディテール・データ・オブジェクトが表示されます。後続の各ディテール・データ・オブジェクトをスクロールするには、フォーム・ナビゲーションを使用する必要があります。
ADFマスター・フォーム、ディテール表: マスター・オブジェクトが読取り専用フォームに表示され、ディテール・オブジェクトがフォームの下にある読取り専用表に表示されます。
フォームに特定のマスター・データ・オブジェクトを表示すると、その下にある表に、関連するディテール・データ・オブジェクトが表示されます。
ADFマスター・フォーム、ディテール・フォーム: マスター・オブジェクトとディテール・オブジェクトが別々のフォームに表示されます。
上のフォームに特定のマスター・データ・オブジェクトを表示すると、その下にあるフォームに、関連する最初のディテール・オブジェクトが表示されます。後続の各ディテール・データ・オブジェクトをスクロールするには、フォーム・ナビゲーションを使用する必要があります。
ADFマスター表、ディテール表: マスター・オブジェクトとディテール・オブジェクトが別々の表に表示されます。
上の表で特定のマスター・データ・オブジェクトを選択すると、その下にある表に、関連する最初のディテール・データ・オブジェクトのセットが表示されます。
デフォルトのフォームまたは表を変更する場合は、第13章「基本的なページの作成」 または第14章「表の追加」を参照してください。
データ・コントロール・パネルからドラッグ・アンド・ドロップを行うと、JDeveloperによって様々な処理が自動的に行われます。たとえば、JSFページにコードが追加され、ページ定義ファイルに対応するエントリが追加されます。データ・コントロール・パレットの使用時に実行される処理と作成される内容の詳細は、12.2.3項「データ・コントロール・パレットの使用時に行われる処理」を参照してください。
基本的に、事前作成済のマスター/ディテール・ウィジェット用に生成されたJSFコードは、データ・コントロール・パレットを使用して基本的な読取り専用の表またはフォームを作成するときに生成されるJSFコードと同じです。詳細は、第13章「基本的なページの作成」および第14章「表の追加」を参照してください。独自のマスター/ディテール・ウィジェットを作成する場合、事前作成済のマスター/ディテール表およびフォームに自動的に組み込まれるものと同様のコンポーネントを組み込むことを検討してみることができます。
事前作成済のマスター/ディテール・ウィジェットの表およびフォームにはpanelHeaderタグがあります。このタグには、フォームまたは表に移入するデータ・オブジェクトの完全修飾名が含まれています。このラベルは、リソース・バンドルにバインドする文字列またはEL式を使用して、必要に応じて変更できます。
コレクション内に複数のデータ・オブジェクトがある場合、事前作成済のマスター/ディテール・ウィジェットのフォームには、レンジ・ナビゲーション用として「先頭へ」、「前へ」、「次へ」および「最後へ」という4つのcommandButtonタグがあります。これらのレンジ・ナビゲーション・ボタンを使用して、コレクション内のデータ・オブジェクトをスクロールできます。各ボタンのactionListenerは、ナビゲーションを実行するデータ・コントロール操作にバインドされています。ボタンをクリックすると、actionListenerバインディングで使用されるexecuteプロパティによって、操作が起動します。(フォームに単一のデータ・オブジェクトが表示されている場合、レンジ・ナビゲーション・コンポーネントは自動的に表示されません。)レンジ・ナビゲーションの詳細は、13.4項「フォームへのレンジ・ナビゲーションの組込み」を参照してください。
事前作成済のマスター/ディテール・ウィジェットの表には、tableSelectOne選択ファセット、およびコレクション内の特定のオブジェクトを選択できる「発行」ボタンがデフォルトで含まれます。デフォルトのボタンはメソッドまたは操作に自動的にはバインドされません。そのため、選択ファセットを機能させるには、アクション・バインディングをボタンに追加する必要があります。たとえば、SRDemoアプリケーションのSRMainページと同じように、選択したデータ・オブジェクトをユーザーが編集できるようにするためのメソッドにボタンをバインドできます。選択ファセットの詳細は、17.3項「メソッドを実行するためのコマンド・コンポーネントの作成」を参照してください。
|
ヒント: ページに「ADFマスター表、ディテール・フォーム」ウィジェットまたは「ADFマスター表、ディテール表」ウィジェットをドロップすると、ディテール・コンポーネントの親タグ(panelFormタグやtableタグなど)のpartialTriggers属性は自動的にマスター・コンポーネントのidに設定されます。実行時に、ユーザーがマスター・コンポーネントで項目を選択すると、partialTriggers属性によりディテール・コンポーネントのみが再レンダリングされます(部分レンダリング)。マスター・コンポーネントが表の場合、ADFでは部分レンダリングが使用されます。ユーザーがファセットで項目を選択した場合、表を再レンダリングする必要はなく、ディテール・コンポーネントのみを再レンダリングして新規データを表示すればよいためです。部分レンダリングの詳細は、19.4項「部分ページ・レンダリングの有効化」を参照してください。 |
例15-1に、ServiceRequestsオブジェクトの下位のディテール・オブジェクトであるServiceHistoriesコレクションを「ADFマスター・フォーム、ディテール表」としてページにドロップして作成されたマスター/ディテール・ページ用に作成されたページ定義ファイルを示します。
executables要素は2つのイテレータを定義しています。1つはサービス・リクエスト(マスター・オブジェクト)用で、1つはサービス履歴(ディテール・オブジェクト)用です。マスター・ビュー・オブジェクトからディテール・ビュー・オブジェクトへの基礎となるビュー・リンクにより、2つのイテレータ間の関係が確立されます。実行時には、ディテール・ビュー・オブジェクト・インスタンスのアクティブ・データ・モデルおよび行セット・イテレータにより、現在の行が変更されたときに、ディテール・ビュー・オブジェクトの行セットが現在のマスター行の正しい行セットになるようにリフレッシュされます(詳細は、15.3.3項「実行時に行われる処理」を参照)。
bindings要素は、フォームおよび表の値バインディングを定義します。フォーム内のテキスト・フィールドに値を移入する属性バインディングは、attributeValues要素内で定義されます。attributeValues要素のid属性には各データ属性の名前が含まれ、IterBinding属性はイテレータ・バインディングを参照し、マスター・オブジェクトのデータをテキスト・フィールドに表示します。
フォーム内のテキスト・フィールドに値を移入する属性バインディングは、attributeValues要素内で定義されます。attributeValues要素のid属性には各データ属性の名前が含まれ、IterBinding属性はイテレータ・バインディングを参照し、マスター・オブジェクトのデータをテキスト・フィールドに表示します。
フォーム内のレンジ・ナビゲーション・ボタンは、action要素で定義されたアクション・バインディングにバインドされます。属性バインディングの場合と同様に、アクション・バインディングのIterBinding属性は、マスター・オブジェクトのイテレータ・バインディングを参照します。
ディテール・データを表示する表は、table要素で定義される表バインディング・オブジェクトにバインドされます。IterBinding属性は、ディテール・オブジェクトのイテレータ・バインディングを参照します。
ページ定義ファイルの要素および属性の詳細は、A.6項「<pageName>PageDef.xml」を参照してください。
例15-1 マスター/ディテール・ページ用にページ定義に定義されたバインディング・オブジェクト
<executables>
<iterator id="ServiceRequestsIterator" RangeSize="10"
Binds="ServiceRequests" DataControl="SRService"/>
<iterator id="ServiceHistoriesIterator" RangeSize="10"
Binds="ServiceHistories" DataControl="SRService"/>
</executables>
<bindings>
<attributeValues id="SvrId" IterBinding="ServiceRequestsIterator">
<AttrNames>
<Item Value="SvrId"/>
</AttrNames>
</attributeValues>
<attributeValues id="Status" IterBinding="ServiceRequestsIterator">
<AttrNames>
<Item Value="Status"/>
</AttrNames>
</attributeValues>
<attributeValues id="RequestDate" IterBinding="ServiceRequestsIterator">
<AttrNames>
<Item Value="RequestDate"/>
</AttrNames>
</attributeValues>
...
<action id="First" RequiresUpdateModel="true" Action="12"
IterBinding="ServiceRequestsIterator"/>
<action id="Previous" RequiresUpdateModel="true" Action="11"
IterBinding="ServiceRequestsIterator"/>
<action id="Next" RequiresUpdateModel="true" Action="10"
IterBinding="ServiceRequestsIterator"/>
<action id="Last" RequiresUpdateModel="true" Action="13"
IterBinding="ServiceRequestsIterator"/>
<table id="ServiceRequestsServiceHistories"
IterBinding="ServiceHistoriesIterator">
<AttrNames>
<Item Value="SvrId"/>
<Item Value="LineNo"/>
...
</AttrNames>
</table>
</bindings>
12.5.2.2項「executables要素で定義されるバインディング・オブジェクト」で説明したように、ADFイテレータは、ページで現在表示されているデータ・オブジェクト(つまり行)がどれかを管理する、基礎となるRowSetIteratorオブジェクトに関連付けられています。実行時には、行セット・イテレータによって、マスター・コンポーネントとディテール・コンポーネントに表示されるデータが管理されます。
マスターおよびディテールの行セット・イテレータは、どちらも行セット・ナビゲーション・イベント(ユーザーによる、特定の行の選択やレンジ・ナビゲーション・ボタンのクリック)をリスニングし、適切な行をUIに表示します。デフォルトのマスター/ディテール・コンポーネントの場合は、行セット・ナビゲーション・イベントは、フォーム上のコマンド・ボタン(「先頭へ」、「前へ」、「次へ」、「最後へ」)または表上の選択ファセットおよび「発行」ボタンになります。
ディテール・コレクションの行セット・イテレータは、ディテール・データとマスター・データの同期化を管理します。マスター・ビュー・オブジェクトからディテール・ビュー・オブジェクトへの基礎となるビュー・リンクのため、ディテール・行セット・イテレータは、マスター・コレクションとディテール・コレクションの両方で行ナビゲーション・イベントをリスニングします。マスター・コレクションで行セット・ナビゲーション・イベントが発生すると、ディテール行セット・イテレータが自動的に実行され、現在のマスター行に関連するディテール行が戻されます。
デフォルトのマスター/ディテール・コンポーネントでは、マスター/ディテール・データは単一のページに表示されます。ただし、データ・コントロール・パレットでマスター・オブジェクトとディテール・オブジェクトを使用して、バインディング・イテレータにマスター・オブジェクトとディテール・オブジェクトの同期化を管理させたまま、コレクションを別々のページに表示することができます。
たとえば、SRDemoアプリケーションでは、サービス・リクエストとサービス履歴が同じSRMainページに表示されます。ただし、ページには、サービス・リクエストのみを表示し、サービス履歴のかわりに「詳細」ボタンを表示させることも可能です。ユーザーが「詳細」ボタンをクリックすると新しいページが表示され、そのページの表に、関連するすべてのサービス履歴が表示されます。ユーザーは、サービス履歴ページのボタンを使用して、サービス・リクエスト・ページに戻ることができます。
マスター/ディテール・オブジェクトを個別のページに表示するには、マスター・オブジェクト用として1ページ、ディテール・オブジェクト用として1ページの計2ページを作成します。その際には、データ・コントロール・パレットから使用できる、個々の表またはフォームを使用します。(個々のフォームまたは表の使用の詳細は、第13章「基本的なページの作成」または第14章「表の追加」を参照してください。)前述のように、ディテール・オブジェクト・イテレータは、マスターとディテールのデータの同期化を管理します。そのため、ディテール・データを表示するページを作成する際には、必ず、データ・コントロール・パレットから適切なディテール・オブジェクトをドラッグしてください(15.2項「データ・コントロール・パレットでのマスター/ディテール・オブジェクトの識別」を参照)。
ページ・ナビゲーションを処理するには、コマンド・ボタンまたはリンクを各ページに追加するか、データ・コントロール・パレットを使用してフォームまたは表を作成するときに使用可能なデフォルトの「発行」ボタンを使用します。各ボタンについて、action属性内で、ナビゲーション・ルールの結果値を指定する必要があります。faces-config.xmlファイルで、マスター・データ・ページからディテール・データ・ページへのナビゲーション・ルール、およびディテール・データ・ページからマスター・データ・ページに戻るための別のルールを追加します。ナビゲーション・ルール内のfrom-outcomeの値は、ボタンのアクション属性で指定された結果値と一致する必要があります。ページ間のナビゲーションの追加に関する詳細は、第16章「ページ・ナビゲーションの追加」を参照してください。
表およびフォーム以外にも、階層ツリーにマスター/ディテール・データを表示することもできます。データ・コントロール・パレットから使用可能なADF Facesのtreeコンポーネントでは、マスター・オブジェクトへのバインディングによって移入された複数のルート・ノードを表示できます。ツリー内の各ルート・ノードは、ディテール・オブジェクトのバインディングによって移入されるブランチを持つことが可能で、その数に制限はありません。ツリーには複数のレベルのノードがあり、各ノードは親ノードのディテール・オブジェクトを示します。ツリー内の各ノードは、階層でのノードのレベルを示します。
treeコンポーネントには、ツリー・ノードを開閉するメカニズムが含まれていますが、フォーカス機能はありません。フォーカス機能が必要な場合は、ADF FacesのTreeTableコンポーネントを使用する方法もあります(詳細は、15.5項「ツリー表を使用したマスター/ディテール・オブジェクトの表示」を参照)。デフォルトでは、ツリーの各ノードのアイコンはフォルダですが、独自のアイコンを階層内の各レベルのノードに使用できます。
図15-4は、SRDemoアプリケーションのSRManageページに含まれるツリーの例を示しています。ツリーには、2つのノード・レベル(スタッフ・メンバーと各メンバーに割り当てられたサービス・リクエスト)が表示されています。ルート・ノードには、スタッフ・メンバーが表示されています。ブランチ・ノードには、各スタッフ・メンバーに割り当てられた未処理または保留中のサービス・リクエストが表示されています。
ツリーはノードの階層で構成され、各サブノードは、上位レベルのノードから分岐します。データ・バインドされたADF Facesのtreeの各ノード・レベルには、異なるデータ・コレクションが移入されます。JDeveloperでは、ツリー・バインディング・エディタを使用してデータ・バインド・ツリーを定義します。これにより、ツリー内の各ノード・レベルに値を移入するための規則を定義できるようになります。階層内の各ノード・レベルに対して1つの規則が必要です。それぞれの規則は、次のノード・レベル・プロパティを定義します。
ノード・レベルを移入するデータ・コレクション。
そのノード・レベルで表示される、データ・コレクションからの属性。
現在のノード・レベルのブランチとして表示されるディテール・オブジェクトを戻すビュー・リンク・アクセッサ(ビュー・リンク・アクセッサの詳細は、第5章「ビュー・リンクを使用したマスター/ディテール階層の作成方法」を参照)。
SRManageページでツリーを作成するために、ビュー・オブジェクトStaffWithOpenRequestsが作成されています。これにより、未処理または保留中のサービス・リクエストを持つユーザーのみが戻されます。もう1つのビュー・オブジェクトOpenOrPendingServiceRequestsも作成され、未処理または保留中のサービス・リクエストがすべて戻されます。また、StaffWithOpenRequestsビュー・オブジェクトからOpenOrPendingServiceRequestsビュー・オブジェクトへのビュー・リンクが作成され、マスター/ディテール関係が確立されています。サービス履歴などの第3レベルのノードを追加するには、サービス・リクエスト・ビュー・オブジェクトからサービス履歴ビュー・オブジェクトへのビュー・リンクが必要です。ビュー・リンクの作成方法の詳細は、5.10項「マスター/ディテール・データでの作業」を参照してください。
ツリーでのマスター/ディテール・オブジェクトの表示方法:
データ・コントロール・パレットからマスター・オブジェクトをドラッグし、ページ上にドロップします。これは、ツリーのルート・レベルを表すマスター・データである必要があります。
ポップアップ・メニューから、「ツリー」→「ADFツリー」を選択します。
JDeveloperによって、図15-5のようにツリー・バインディング・エディタが表示されます。
ツリー・バインディング・エディタの「規則の編集」ページで、ツリーに表示する各ノード・レベルの規則を定義します。規則を定義するには、次の項目を選択する必要があります。
データ・コレクション定義: 定義するノード・レベルに移入するデータ・コレクションを選択します。
最初の規則はルート・ノード・レベルを定義します。そのため、最初の規則については、データ・コントロール・パレットからドラッグしたものと同じコレクション(マスター・コレクション)を選択して、ツリーを作成します。
ブランチ・ノードを作成するには、適切なディテール・コレクションを選択します。たとえば、ユーザーのルート・ノードを作成するために、最初(ルート・ノード)の規則に対してUserコレクションを選択し、サービス・リクエストを表示するブランチを作成するために、ブランチ規則でServiceRequestコレクションを選択します。
属性の表示: 各ノード・レベルで表示する1つ以上の属性を選択します。たとえば、ユーザーのノードに対して、FirstName属性およびLastName属性の両方を選択できます。
ブランチ規則アクセッサ: 定義するノード・レベルの下にブランチとして表示させるディテール・コレクションを戻す、ビュー・リンク・アクセッサ属性を選択します。リストには、規則に対して選択したマスター・コレクションのディテール・コレクションを戻すアクセッサ属性のみが表示されます。「<none>」を選択した場合は、ノードが開かずディテール・コレクションは表示されないため、ブランチは分岐しません。たとえば、Userノード・レベルを定義する場合に各ユーザーのサービス・リクエストにブランチを追加するには、サービス・リクエスト・コレクションを戻すアクセッサ属性を選択できます。その後、ServiceRequestノード・レベルの新しい規則を定義する必要があります。
データ・コレクションを戻すビュー・リンク・アクセッサ属性は、ビュー・リンクの作成時に生成されます。「ブランチ規則アクセッサ」フィールドには、「データ・コレクション定義」フィールドで選択したマスター・コレクションのディテール・コレクションを戻すアクセッサ属性がすべて表示されます。ビュー・オブジェクト、ビュー・リンクおよびビュー・リンク・アクセッサの詳細は、第5章「ビュー・オブジェクトを使用したデータの問合せ」を参照してください。
多相制限: 必要に応じて、属性のノード移入規則を定義して、その属性の値を識別子にすることができます。それぞれの規則が一意の識別子値を指定しているかぎり、同じ属性に対して必要な数だけノード移入規則を定義できるため、規則は多相になります。ツリーには、多相規則ごとに別個のブランチが表示され、属性の識別子値と同じノードが使用されます。
|
ヒント: それぞれの規則を定義した後は、必ず「新しい規則を追加」をクリックしてください。これをクリックせずに「OK」をクリックすると、最後に定義した規則は保存されません。「新しい規則を追加」をクリックすると、JDeveloperによってツリー・バインディング・エディタの「規則の表示」タブが表示され、作成した規則を確認できます。 |
図15-6に示すツリー・バインディング・エディタの「規則の表示」ページを使用して、次の処理を行います。
規則の順序変更
規則の順序は、ツリーで表示する階層を反映する必要があります。
規則の削除
|
注意: ADF FacesまたはJSFのツリー・コンポーネントに表示されているアイコンは変更できません。 |
ツリー・バインディング・エディタの「規則の表示」ページに表示される最初の規則によって、ツリーのルート・ノード・レベルに値が移入されます。そのため、データ・モデルの構造に応じて、最初の規則によってツリーの論理的なルート・ノードに値が移入されることを確認してください。
図15-4で示したツリーの例の場合、最初の規則は、ユーザー・ノードに値を移入する規則になります。残りの規則の順序は、ツリーに表示するノードの階層に従う必要があります。
データ・コントロール・パレットからドラッグ・アンド・ドロップを行うと、JDeveloperによって様々な処理が自動的に行われます。データ・コントロール・パレットの使用時に実行される処理と作成される内容の詳細は、12.2.3項「データ・コントロール・パレットの使用時に行われる処理」を参照してください。
データ・コントロール・パレットを使用してデータ・バインドされたツリーを作成すると、JDeveloperによって、ページ定義ファイルにバインディング・オブジェクトが追加され、JSFページにツリー・タグが追加されます。作成されたUIコンポーネントは、そのままで十分機能するため、変更する必要はありません。
例15-2は、データ・コントロール・パレットを使用してツリーを作成する際に、JSFページで生成されるコードを示しています。このツリーには、ユーザーおよびサービス・リクエストの2つのノード・レベルが表示されます。ユーザーを表示するルート・ノードに値を移入するために、LoggedInUserコレクションが使用されています。
例15-2 データ・バインド・ツリー用にJSFページで生成されたコード
<h:form>
<af:tree value="#{bindings.StaffWithOpenRequests.treeModel}" var="node">
<f:facet name="nodeStamp">
<af:outputText value="#{node}"/>
</f:facet>
</af:tree>
</h:form>
デフォルトで、フォームの中にaf:treeタグが作成されます。ツリー・タグのvalue属性には、ツリー・コンポーネントをページ定義ファイルのLoggedInUserツリー・バインディング・オブジェクトにバインドするEL式が含まれます。バインディング式のtreeModelプロパティによって、基礎となるデータ・モデルに基づいてツリー階層の表示方法を定義する、ADFクラスが参照されます。var属性は、現在のノードへのアクセスを提供します。
f:facetタグに含まれるnodeStampファセットは、各ノードのデータを表示するために使用されます。ノードごとにコンポーネントを持つかわりに、ツリーでは、ADF Faces表コンポーネントに対して行がレンダリングされるのと同様の方法で、nodeStampファセットが繰返しレンダリングされます。
ADF Facesツリー・コンポーネントでは、oracle.adf.view.faces.model.PathSetクラスのインスタンスを使用して、開いた状態のノードが表示されます。このインスタンスは、コンポーネントのtreeState属性として格納されます。このインスタンスを使用して、階層での要素の開閉状態をプログラム的に管理できます。PathSetインスタンスに含まれるすべての要素は、開いた状態とみなされます。その他のすべての要素は閉じた状態です。
例15-3は、ADFデータ・バインド・ツリーに対してページ定義ファイルで定義されたバインディング・オブジェクトを示しています。
例15-3 データ・バインド・ツリー用にページ定義ファイルで定義されたバインディング・オブジェクト
<executables>
<iterator id="StaffWithOpenRequestsIterator" RangeSize="10"
Binds="StaffWithOpenRequests" DataControl="SRService"/>
</executables>
<bindings>
<tree id="StaffWithOpenRequests"
IterBinding="StaffWithOpenRequestsIterator">
<AttrNames>
<Item Value="UserId"/>
<Item Value="FirstName"/>
<Item Value="LastName"/>
</AttrNames>
<nodeDefinition DefName="oracle.srdemo.model.queries.StaffWithOpenRequests"
id="StaffWithOpenRequestsNode">
<AttrNames>
<Item Value="FirstName"/>
<Item Value="LastName"/>
</AttrNames>
<Accessors>
<Item Value="OpenOrPendingServiceRequests"/>
</Accessors>
</nodeDefinition>
<nodeDefinition id="OpenOrPendingServiceRequestsNode"
DefName="oracle.srdemo.model.queries.OpenOrPendingServiceRequests">
<AttrNames>
<Item Value="Status"/>
<Item Value="ProblemDescription"/>
</AttrNames>
</nodeDefinition>
</tree>
</bindings>
ページ定義ファイルには、ツリー・バインディング・エディタで定義された規則情報が含まれます。executables要素では、2つのノード・レベルがツリーに表示されても、1つのイテレータ・バインディング・オブジェクトしか要求されません。このイテレータは、ツリーのルート・ノードに移入するマスター・コレクションを反復処理します。このノードで指定したアクセッサは、各ブランチのディテール・データを戻します。
tree要素は、ツリーに表示されるすべての属性の値バインディングです。tree要素のIterBinding属性は、ツリーにデータを移入するイテレータ・バインディングを参照します。tree要素内のAttrNames要素は、マスター・コレクション内のすべての属性のバインディング・オブジェクトを定義します。ただし、ツリーに表示するように選択する属性は、nodeDefinition要素内のAttrNames要素で定義されます。
nodeDefinition要素は、ツリーのノードを移入するための規則を定義します。ノードごとに1つのnodeDefinition要素があり、各要素には次の属性およびサブ要素が含まれます。
id: ノードの名前を定義する属性。
ページ定義ファイルでのnodeDefintion要素の順序は、ツリーでのノードの順序またはレベルを定義します。先頭のnodeDefinition要素は、ルート・ノードを定義します。後続の各nodeDefinition要素は、先行するノードのサブノードを定義します。
ページ定義ファイルの要素および属性の詳細は、A.6項「<pageName>PageDef.xml」を参照してください。
ツリー・コンポーネントは、oracle.adf.view.faces.model.TreeModelを使用してデータにアクセスします。このクラスは、ADF Facesのtableコンポーネントがデータへのアクセスに使用するCollectionModelを拡張します。TreeModelクラスの詳細は、ADF Faces Javadocを参照してください。
ツリーを含むページが表示されると、ツリー上のイテレータ・バインディングによって、ルート・ノードに値が移入されます。ユーザーがノードを開いてブランチを表示したり、閉じて非表示にすると、DisclosureEventイベントが送信されます。このイベントのisExpandedメソッドは、ユーザーの操作に基づいてノードを開くか閉じるかを判断します。DisclosureEventイベントには、リスナーが関連付けられています。
ツリー上のDisclosureListener属性は、ページ定義ファイルで定義済のノード規則で指定されたアクセッサ属性にバインドされます。このアクセッサ属性は、DisclosureEventイベントに反応して起動します。つまり、ユーザーがノードを開くたびに、アクセッサ属性によってブランチ・ノードに値が移入されます。
ルート・ノードにスタッフ・メンバーを表示し、ブランチ・ノードにサービス・リクエストを表示するSRDemoアプリケーションのSRManageページ上のツリー・コンポーネントは、データ・コントロール・パレットで使用可能なデフォルトのツリー・コンポーネントを使用して作成されたものです。ただし、ツリーの各ノードには、そのノードに関する追加ディテール・データを個別のUIコンポーネントとして動的に表示するコマンド・リンクが含まれます。たとえば、ユーザーがスタッフ・メンバーをクリックすると、図15-7のように、関連する専門技術領域(ディテール・オブジェクト)がツリーの右側の表に表示されます。
これを機能的に実現するために、ADF Facesのswitcherコンポーネントがtreeタグのnodestampファセットに手動で追加されています。これにより、ユーザーがコマンド・リンクをクリックしたときに、ディテール・オブジェクトのデータが動的に表示されます。
例15-4に示すswitcherコンポーネントでは、facetName属性には、faces-config.xmlファイルでマネージドBeanとして構成されているSRManageバッキングBean上のJSFバインディングが含まれています。このバッキングBeanには、faces-config.xmlファイルで管理プロパティとして宣言的に定義されているMap型のtreeLevelプロパティがあります。
例15-4 ADF Facesのswitcherコンポーネント
<af:switcher facetName="#{backingSRManage.treeLevel[node.hierType.viewDefName]}">
<f:facet name="StaffNode">
<af:commandLink text="#{node}"
action="#{backing_SRManage.staffLinkDrilldown}"
actionListener="#{bindings.setCurrentStaffRowWithKey.execute}"/>
</f:facet>
<f:facet name="ServiceRequestsNode">
<af:panelGroup>
<af:outputText value="[#{node.Status}] "/>
<af:commandLink text="#{node.ProblemDescription}"
action="#{backing_SRManage.problemLinkDrilldown}"
actionListener="#{bindings.setCurrentProblemAndAssigneeRows.execute}"/>
</af:panelGroup>
</f:facet>
</af:switcher>
faces-config.xml内の管理プロパティ定義には、例15-5のように、キー値のペア(viewdefinitionname、facetname)をtreeLevel Mapに挿入する情報が含まれています。Mapは、様々なビュー・オブジェクト・タイプごとに異なるプレゼンテーションをツリーに表示するために使用されます。
例15-5 faces-config.xmlファイルにおけるtreeLevel管理プロパティ定義
<managed-bean>
<managed-bean-name>backing_SRManage</managed-bean-name>
...
<managed-property>
<property-name>treeLevel</property-name>
<map-entries>
<key-class>java.lang.String</key-class>
<value-class>java.lang.String</value-class>
<map-entry>
<key>oracle.srdemo.model.queries.StaffWithOpenRequests</key>
<value>StaffNode</value>
</map-entry>
<map-entry>
<key>oracle.srdemo.model.queries.OpenOrPendingServiceRequests</key>
<value>ServiceRequestsNode</value>
</map-entry>
</map-entries>
</managed-property>
</managed-bean>
ツリーのノードにコマンド・リンクを追加すると、実行時にユーザーは、ツリーに移入するイテレータ内の現在オブジェクトではないリンクをクリックできるようになります。(イテレータ内の現在オブジェクトは、ユーザーが最後にツリー・ノードを開いたときに表示されたオブジェクトです。)このため、正しいディテール・オブジェクトを表示するには、コマンド・リンクは、イテレータ内の現在のオブジェクトをプログラム的に設定する操作またはメソッドにバインドされている必要があります。たとえば、SRManageページの場合、サービス・リクエスト・ノード上のコマンド・リンクは、現在のオブジェクトをプログラム的に設定するsetCurrentProblemAndAssigneeRowsメソッドにバインドされています。コマンド・コンポーネントにおける現在オブジェクトの手動設定の詳細は、14.7項「コマンド・コンポーネントを使用した現在オブジェクトの設定」を参照してください。ADF Facesのswitcherコンポーネントの詳細は、ADF FacesのJavadocを参照してください。
ADF FacesのtreeTableコンポーネントを使用すると、マスター/ディテール・コレクションの階層を表に表示できます。treeコンポーネントのかわりにtreeTableコンポーネントを使用することの利点は、treeTableコンポーネントがツリー内の特定のノードにフォーカスして表示するメカニズムを使用できることです。
図15-8は、ユーザー、サービス・リクエストおよびサービス履歴という3つのノード・レベルを表示するツリー表の例を示しています。各ルート・ノードは、個別のユーザーを表します。各ルート・ノードが分岐して、そのユーザーに関連付けられているサービス・リクエストが表示されます。また、各サービス・リクエスト・ノードが分岐して、各サービス・リクエストのサービス履歴が表示されます。
ツリーの場合と同様、複数のノードがあるツリー表を作成するには、ビュー・オブジェクト間のビュー・リンクを作成する必要があります。ビュー・リンクにより、マスター/ディテール関係が確立されます。たとえば、図15-8に示すツリー表を作成するには、ユーザー・ビュー・オブジェクトからサービス・リクエスト・ビュー・オブジェクトへのビュー・リンク、およびサービス・リクエスト・ビュー・オブジェクトからサービス履歴ビュー・オブジェクトへの別のビュー・リンクを作成する必要があります。ビュー・リンクの作成方法の詳細は、5.10項「マスター/ディテール・データでの作業」を参照してください。
データ・バインドされたADF FacesのtreeTableには、一度に1つのルート・ノードしか表示されませんが、様々なルート・ノードをスクロールするためのナビゲーションが用意されています。各ルート・ノードには、任意の数のブランチ・ノードを表示できます。各ノードは表の個別の行として表示され、各行の左端の列にはフォーカス・メカニズムが付属します。
ADF FacesのtreeTableコンポーネントには、次の組込み機能が含まれます。
レンジ・ナビゲーション: ユーザーは、「前へ」および「次へ」のナビゲーション・ボタンをクリックして、ルート・ノードをスクロールできます。
リスト・ナビゲーション: 「前へ」ボタンと「次へ」ボタンの間にあるリスト・ナビゲーションにより、ユーザーは、選択リストを使用してデータ・コレクション内の特定のルート・ノードに移動できます。
ノードを開閉するためのメカニズム: ユーザーは、それぞれのノードを個別に開閉するか、「すべて展開」または「すべて閉じる」のコマンド・リンクを使用できます。デフォルトでは、個々のノードの開閉を示すアイコンは、プラスまたはマイナス記号付きの矢印です。カスタム・アイコンを選択して使用することもできます。
フォーカス・メカニズム: ユーザーがノードの横(左端の列)のフォーカス・アイコンをクリックすると、ページが再表示され、ノードとそのブランチのみが表示されます。親ノードに戻るためのナビゲーション・リンクも表示されます。
ADF Facesデータ・バインド・ツリー表の作成手順は、ADF Facesデータ・バインド・ツリーの作成手順とほぼ同じですが、データ・コレクションをドロップする際に、ADFツリーとしてではなくADFツリー表としてドロップします。詳細は、15.4.1項「ツリーでのマスター/ディテール・オブジェクトの表示方法」を参照してください。
データ・コントロール・パレットからドラッグ・アンド・ドロップを行うと、JDeveloperによって様々な処理が自動的に行われます。データ・コントロール・パレットの使用時に実行される処理と作成される内容の詳細は、12.2.3項「データ・コントロール・パレットの使用時に行われる処理」を参照してください。
データ・コントロール・パレットを使用してデータ・バインド・ツリー表を作成すると、JDeveloperによって、ページ定義ファイルにバインディング・オブジェクトが追加され、JSFページにtreeTableタグが追加されます。作成されたUIコンポーネントは、そのままで十分機能するため、変更する必要はありません。
例15-6は、データ・コントロール・パレットを使用してツリー表を作成する際に、JSFページで生成されるコードを示しています。このツリー表には、ユーザー、サービス・リクエストおよびサービス履歴の3つのノード・レベルが表示されます。
デフォルトで、フォームの中にtreeTableタグが作成されます。ツリー表タグのvalue属性には、ツリー・コンポーネントを、そのデータを移入するバインディング・オブジェクト(この例ではLoggedInUserツリー・バインディング・オブジェクト)にバインドするEL式が含まれます。treeModelプロパティは、基礎となるデータ・モデルに基づいてツリー階層の表示方法を定義する、ADFクラスを参照します。var属性は、現在のノードへのアクセスを提供します。
例15-6 データ・バインドされたADF Facesツリー表用にJSFページで生成されたコード
<h:form>
<af:treeTable value="#{bindings.LoggedInUser.treeModel}" var="node">
<f:facet name="nodeStamp">
<af:column>
<af:outputText value="#{node}"/>
</af:column>
</f:facet>
<f:facet name="pathStamp">
<af:outputText value="#{node}"/>
</f:facet>
</af:treeTable>
</h:form>
facetタグに含まれるnodeStampファセットは、各ノードのデータを表示するために使用されます。ノードごとにコンポーネントを持つかわりに、ツリーでは、ADF Faces表コンポーネントに対して行がレンダリングされるのと同様の方法で、nodeStampファセットが繰返しレンダリングされます。pathStampファセットは、ユーザーがディテール・ノードにフォーカスした後で親ノードに戻れるように、表の上に列およびパスのリンクをレンダリングします。
ツリー表に対してページ定義ファイルで作成されるバインディング・オブジェクトは、ツリーに対して作成されるものとまったく同じです。ツリー・バインディング・オブジェクトの詳細は、15.4.2.2項「ページ定義ファイルに定義されるバインディング・オブジェクト」を参照してください。
ツリー・コンポーネントは、oracle.adf.view.faces.model.TreeModelを使用してデータにアクセスします。このクラスは、ADF Facesのtableコンポーネントがデータへのアクセスに使用するCollectionModelを拡張します。TreeModelクラスの詳細は、ADF Faces Javadocを参照してください。
ツリー表を含むページが表示されると、treeTableコンポーネントのイテレータ・バインディングは、ルート・ノードに値を移入し、行ナビゲーション・イベント(ユーザーによる「次へ」ボタンまたは「前へ」ボタンのクリック、もしくはレンジ・ナビゲータからの行の選択)をリスニングします。ユーザーが行ナビゲーション・イベントを開始すると、イテレータによって適切な行が表示されます。
ユーザーがコンポーネントのフォーカス・アイコンをクリックして表示のフォーカスを変更すると、treeTableコンポーネントによってフォーカス・イベント(FocusEvent)が生成されます。フォーカス変更後のノードが現在のノードになった後で、イベントが配信されます。その後、treeTableコンポーネントによってfocusPathプロパティが適切に変更されます。ツリー上のFocusListener属性をマネージドBean上のメソッドにバインドできます。これにより、このメソッドはフォーカス・イベントに応じて起動されます。
ユーザーがノードを開閉するたびに、公開イベント(DisclosureEvent)が送信されます。この公開イベントのisExpandedメソッドは、ユーザーの操作に基づいてノードを開くか閉じるかを判断します。公開イベントには、リスナーDisclosureListenerが関連付けられます。ツリー表上のDisclosureListener属性は、ページ定義ファイルで定義済のノード規則で指定されたアクセッサ属性にバインドされます。このアクセッサ属性は、公開イベント(ユーザーがノードを開くなど)に応じて起動し、そのノードに移入されるコレクションを戻します。
treeTableコンポーネントには、「すべて展開」リンクおよび「すべて閉じる」リンクも表示されます。ユーザーがどちらかのリンクをクリックすると、treeTableによってDisclosureAllEventイベントが送信されます。このイベントのisExpandedメソッドは、ユーザーの操作に基づいてすべてのノードを開くか閉じるかを判断します。その後、現在フォーカスしているルート・ノードの子ノードが、開くか閉じます。大規模なツリーの場合は、すべて展開コマンドを使用しても、直下の子より下にあるノードは開きません。ADF FacesのtreeTableコンポーネントでは、oracle.adf.view.faces.model.PathSetクラスのインスタンスを使用して、開いたノードが判別されます。このインスタンスは、コンポーネントのtreeState属性として格納されます。このインスタンスを使用して、階層でのノードの開閉状態をプログラム的に管理できます。PathSetインスタンスに含まれるすべてのノードは、開いているとみなされます。その他のすべてのノードは閉じた状態になります。このクラスでは、addAll()やremoveAll()のような操作もサポートされます。
ADF Facesのtableコンポーネントと同様に、treeTableコンポーネントでは、レンジ・ナビゲーションを使用できます。ただし、treeTableコンポーネントでは、rows属性のかわりにrowsByDepth属性が使用されます。この属性の値は、スペースで区切られた正数のリストです。それぞれの数字は、ツリー上のノード・レベルのレンジ・サイズを定義します。最初の数字はツリーのルート・ノードで、最後の数字はブランチ・ノードに対応します。ツリーのブランチの数がrowsByDepth属性に含まれる数字より多い場合は、残りのブランチに対して、リストの最後の数字が使用されます。各数字は、各ブランチに一度に表示される項目数の制限を定義します。ブランチにすべての項目を表示するには、リストの対応する位置で0を指定します。
たとえば、rowsByDepth属性が0 0 3に設定されている場合は、ルート・ノードおよびその直下にある子はすべて表示されますが、それより下は、ブランチごとに3つのノードしか表示されません。ただし、treeTableコンポーネントには追加のノードに移動するためのリンクが含まれるため、ユーザーは追加のノードを表示できます。
ADF FacesのTreeTableコンポーネントの詳細は、ADF Faces Javadocのoracle.adf.view.faces.component.core.data.CoreTreeTableクラスを参照してください。
14.5項「表への非表示機能の追加」で説明したように、表のdetailStampファセットを使用すると、表に含まれる特定のデータ・オブジェクトに関する追加情報を表示したり、非表示にすることができます。このファセットにコンポーネントを追加すると、表に「詳細」ラベルが付いた追加の列が表示され、この列に追加情報が表示されます。この列には切替えのメカニズムが組み込まれており、ユーザーは、ADF FacesのtreeまたはtreeTableコンポーネントと同様の方法で、「詳細」列に表示される情報を非表示にしたり表示することができます。14.5項「表への非表示機能の追加」で説明したケースでは、追加の情報は、表に移入されるものと同じデータ・コレクションからの単一の属性でした。
データ・コントロール・パレットでマスター・ディテール・コレクションを使用すると、ディテール・コレクションからの追加情報を表示するdetailStampファセットに、宣言的にインライン表を追加できます。マスター・コレクションはメイン表の移入に使用され、ディテール・コレクションはインライン表の移入に使用されます。
図15-9は、サービス・リクエストのインライン表がサービス・リクエスト・スタッフの表にどのように埋め込まれるかを示しています。ユーザーが表ファセットに組み込まれている「詳細」列の「表示」リンクをクリックすると、表の選択した行の下に、サービス・リクエストのインライン表が表示されます。ユーザーのマスター・コレクションがメイン表に移入され、ユーザーの姓名が表示されます。サービス・リクエストのディテール・コレクションがインライン表に移入され、サービス・リクエスト問題の説明とステータスが表示されます。
データ・コントロール・パレットを使用して、メイン表とインライン表を単一の宣言的アクションで作成できます。インライン表はツリー表と類似しているため、ツリー・バインディング・エディタを使用して、メイン表およびインライン・ディテール表への移入の規則を定義できます。メイン表とインライン・ディテール表には、それぞれ1つの規則が必要になります。各規則によって、次のプロパティが定義されます。
表に移入するデータ・コレクション
表に表示されるデータ・コレクションの属性
メイン表の規則では、インライン表に移入するディテール・コレクションを戻すビュー・リンク・アクセッサ属性も指定する必要があります。ビュー・リンク・アクセッサの詳細は、5.10.2項「ビュー・リンクを使用したマスター/ディテール階層の作成方法」を参照してください。
インライン・ディテール表を伴うマスター表の作成手順:
データ・コントロール・パレットからマスター・データ・オブジェクトをドラッグし、ページ上にドロップします。これは、メイン表に移入するマスター・オブジェクトであることが必要です。
ポップアップ・メニューから「表」→「ADFマスター表、インライン・ディテール表」を選択します。
JDeveloperによって、前の図15-5のように、ツリー・バインディング・エディタが表示されます。
ツリー・バインディング・エディタの「規則の編集」ページで、メイン表の移入規則およびインライン表の移入規則を定義します。規則を定義するには、次の項目を選択する必要があります。
データ・コレクション定義: 定義する表に移入するデータ・コレクションを選択します。最初の規則によってメイン表が定義されます。そのため、最初の規則については、データ・コントロール・パレットからドラッグしたものと同じデータ・コレクション(マスター・コレクション)を選択します。インライン表の規則を定義する際には、適切なディテール・コレクションを選択します。たとえば、ユーザーのメイン表を作成するために、最初の規則に対してUserコレクションを選択し、ユーザーに関連するサービス・リクエストを表示するインライン表を作成するために、ブランチ規則でServiceRequestコレクションを選択します。
属性の表示: 定義する表に表示する1つ以上の属性を選択します。各属性は、表の1つの列になります。たとえば、メイン表にユーザーを表示する場合は、firstName属性およびlastName属性の両方を選択できます。
ブランチ規則アクセッサ: メイン表の規則を定義する場合は、インライン・ディテール表に表示するディテール・コレクションを戻すアクセッサ属性を選択します。リストには、規則に対して選択したマスター・コレクションのディテール・コレクションを戻すアクセッサ属性のみが表示されます。インライン表の規則を定義する場合は、「<none>」を選択します。これは、インライン表には表を埋め込めないためです。
データ・コレクションを戻すビュー・リンク・アクセッサ属性は、ビュー・リンクの作成時に生成されます。「ブランチ規則アクセッサ」フィールドには、「データ・コレクション定義」フィールドで選択したマスター・コレクションのディテール・コレクションを戻すビュー・リンク・アクセッサがすべて表示されます。ビュー・オブジェクトおよびビュー・リンクの詳細は、第5章「ビュー・オブジェクトを使用したデータの問合せ」を参照してください。
|
ヒント: それぞれの規則を定義した後は、必ず「新しい規則を追加」ボタンをクリックしてください。これをクリックせずに「OK」ボタンをクリックすると、最後に定義した規則は保存されません。「新しい規則を追加」をクリックすると、JDeveloperによってツリー・バインディング・エディタの「規則の表示」タブが表示され、作成した規則を確認できます。 |
図15-6に示すツリー・バインディング・エディタの「規則の表示」ページを使用して、次の処理を行います。
規則の順序変更
メイン表の移入の規則は、リストの最初に配置する必要があります。
開閉のメカニズムに使用するアイコンの識別
これらのアイコンはメイン表でのみ使用されるため、デフォルト以外のアイコンを使用する場合は、メイン表の規則で指定します。
デフォルトのオープン・アイコンは、マイナス記号付きの、塗りつぶされた下向き矢印で、デフォルトのクローズ・アイコンは、プラス記号付きの、塗りつぶされた右向き矢印です。
規則の削除
データ・コントロール・パレットからドラッグ・アンド・ドロップを行うと、JDeveloperによって様々な処理が自動的に行われます。データ・コントロール・パレットの使用時に実行される処理と作成される内容の詳細は、12.2.3項「データ・コントロール・パレットの使用時に行われる処理」を参照してください。
データ・コントロール・パレットを使用してマスター表およびインライン・ディテール表を作成すると、JDeveloperによって、ページ定義ファイルにバインディング・オブジェクトが追加され、JSFページに表およびファセットが追加されます。作成されたUIコンポーネントは、そのままで十分機能するため、変更する必要はありません。
例15-7は、JSFページで生成されたコードを示しています。この例では、メイン表にユーザーが表示され、インライン・ディテール表にサービス・リクエストが表示されます。メイン表は、その他のADFデータ・バインド表と同様に定義されます。この表は、ツリー・バインディング・オブジェクトである、ページ定義ファイル内のLoggedInUserバインディング・オブジェクトにバインドされます。メイン表の列には、ユーザーの姓名が表示されます。表には、ディテール表が定義されるdetailStampファセットが含まれます。ディテール表もLoggedInUserツリー・バインディング・オブジェクトにバインドされ、列はサービス・リクエスト・コレクションからのデータを表示するように設定されます。ツリー・コンポーネントの場合と同様に、ページ定義ファイルは、ディテール・コレクションを戻すアクセッサ属性を定義します。
例15-7 インライン・ディテール表を伴うマスター表に対して作成されるJSFコード
<af:table rows="#{bindings.LoggedInUser.rangeSize}"
emptyText="#{bindings.LoggedInUser.viewable ? \'No rows yet.\' :
\'Access Denied.\'}"
var="row" value="#{bindings.LoggedInUser.treeModel}">
<af:column headerText="#{bindings.LoggedInUser.labels.FirstName}"
sortable="false" sortProperty="FirstName">
<af:outputText value="#{row.FirstName}"/>
</af:column>
<af:column headerText="#{bindings.LoggedInUser.labels.LastName}"
sortable="false" sortProperty="LastName">
<af:outputText value="#{row.LastName}"/>
</af:column>
<f:facet name="detailStamp">
<af:table rows="#{bindings.LoggedInUser.rangeSize}"
emptyText="No rows yet." var="detailRow"
value="#{row.children}">
<af:column headerText="#{row.children[0].labels.Status}"
sortable="false" sortProperty="Status">
<af:outputText value="#{detailRow.Status}"/>
</af:column>
<af:column headerText="#{row.children[0].labels.ProblemDescription}"
sortable="false" sortProperty="ProblemDescription">
<af:outputText value="#{detailRow.ProblemDescription}"/>
</af:column>
</af:table>
</f:facet>
</af:table>
例15-8は、インライン・ディテール表を伴うマスター表に対してページ定義ファイルに追加されるバインディング・オブジェクトを示しています。executables要素は、メイン表にLoggedInUserコレクションのデータを表示する、LoggedInUserIteratorというイテレータ・バインディングを定義します。ディテール・コレクションにはイテレータ・バインディングは不要です。これは、ツリー・バインディング・オブジェクト内で参照されるアクセッサ属性によって、現在選択されているマスター・データに関連するディテール・データが戻されるためです。
bindings要素では、ツリー・バインディング・オブジェクトは、マスター表およびディテール表にデータを移入します。nodeDefintion要素は、マスター表およびディテール表の列に表示される属性を定義します。最初のnodeDefinition要素はマスター表のデータを定義し、2番目はインライン・ディテール表のデータを定義します。ツリー・バインディング・オブジェクトの詳細は、15.4.2項「ADFデータ・バインド・ツリーの作成時に行われる処理」を参照してください。
例15-8 インライン・ディテール表を伴うマスター表に対してページ定義ファイルに追加されるバインディング・オブジェクト
<executables>
<iterator id="LoggedInUserIterator" RangeSize="10" Binds="LoggedInUser"
DataControl="SRService"/>
</executables>
<bindings>
<tree id="LoggedInUser" IterBinding="LoggedInUserIterator">
<AttrNames>
<Item Value="UserId"/>
<Item Value="Email"/>
<Item Value="FirstName"/>
<Item Value="LastName"/>
</AttrNames>
<nodeDefinition DefName="oracle.srdemo.model.queries.LoggedInUser"
id="LoggedInUserNode">
<AttrNames>
<Item Value="FirstName"/>
<Item Value="LastName"/>
</AttrNames>
<Accessors>
<Item Value="ServiceRequestsByStatus"/>
</Accessors>
</nodeDefinition>
<nodeDefinition DefName="oracle.srdemo.model.queries.ServiceRequestsByStatus"
id="ServiceRequestsByStatusNode">
<AttrNames>
<Item Value="Status"/>
<Item Value="ProblemDescription"/>
</AttrNames>
</nodeDefinition>
</tree>
</bindings>
ユーザーが「非表示」リンクまたは「表示」リンクをクリックして行の詳細を非表示にしたり表示したりするたびに、表によって、インライン・ディテール表を開閉するDisclosureEventイベントが生成されます。このイベントのisExpandedメソッドは、ユーザーの操作に基づいてディテール表を開くか閉じるかを判別します。
DisclosureEventイベントには、リスナーが関連付けられています。表にあるDisclosureListener属性は、ページ定義ファイルで定義済のノード規則で指定されたアクセッサ属性に暗黙的にバインドされます。このアクセッサ属性は、DisclosureEventイベントに応じて起動します。たとえば、ユーザーが「表示」リンクをクリックすると、アクセッサ属性が起動し、データをインライン表に移入します。