この章では、ページにより複雑なバインディングを追加する方法について説明します。内容には、フォームおよびコマンド・コンポーネントを作成するためのパラメータを取得するメソッドの使用方法などが含まれます。
この章の内容は次のとおりです。
基本的なページを作成してナビゲーション機能を追加したら、ページ間でパラメータ値を渡したり、特定のレコードを検索して戻すなどの、より複雑な機能をページに追加できます。ADFには、このような複雑な機能を実際のコードをほとんど使用せずに追加できる機能が用意されています。
たとえば、サービスBeanに対してメソッドを直接実行する、ボタンなどのコマンド・コンポーネントを作成できます。これは、データ・コントロールからメソッドをドラッグし、コマンド・ボタンとしてドロップするだけで行えます。コマンド・コンポーネントを使用して、別のページにパラメータ値を渡すこともできます。
データ・ストアからの情報を表示する基本的なフォームを作成するだけでなく、(パラメータ値によって判別される)特定のレコードのみを表示するフォーム、新規レコードを作成できるフォーム、およびユーザー入力に基づいてオブジェクトを検索して戻すフォームなども作成できます。
この章では次の内容について説明します。
マネージドBeanを使用したパラメータ値またはフラグの格納方法
メソッドにバインドされたコマンド・コンポーネントの作成方法
パラメータ値の設定方法
コマンド・コンポーネントにバインドされたメソッドへのロジックの追加方法
特定のレコードのみを表示するフォームおよび表の作成方法
ユーザーが新規レコードを作成できるフォームの作成方法
結果表が表示される検索フォームの作成方法
ページに正しい情報を表示するために、他のページの情報が必要になることがよくあります。そのページのページ定義ファイルにパラメータ値を設定するなどして、この情報をページに直接設定すると、本質的に情報がハードコード化されます。これにかわる方法として、この情報をマネージドBeanに格納できます。Beanがアクセス可能なスコープ内に格納されているかぎり、Beanの属性のすべての値に、EL式を使用してアクセスできます。
たとえば、SREditページでは、前のページでユーザーが選択した行のsvrId属性の値が要求されます。この値は、フォームの表示に使用されるfindServiceRequestById(Integer)メソッドのパラメータ値を提供します。また、「取消」ボタンにバインドされたメソッドは、ユーザーが正しいページに戻れるように、結果を戻す必要があります(SREditページは3つの異なるページからアクセスできます)。SRDemoアプリケーションでは、この情報を保持するマネージドBeanが存在するため、情報を送る側のページで情報を設定できます。また、SREditページでこの情報を使用することで、取消アクションに対する移動先が判別されます。この情報はBeanにハッシュ・マップとして格納されます。
マネージドBeanは、faces-config.xmlファイルを使用してアプリケーションに登録するJavaクラスです。JSFアプリケーションの起動時に、この構成ファイルおよびBeanが使用可能になり、EL式で参照できるようになります。これにより、Beanのプロパティおよびメソッドへのアクセスが可能になります。マネージドBeanが初めて参照されるときに存在しない場合は常に、マネージドBean作成機能によってそのBeanのデフォルト・コンストラクタ・メソッドがコールされ、Beanがインスタンス化されます。プロパティも宣言された場合は、宣言済のデフォルト値が移入されます。
JDeveloperのJSF構成エディタを使用すると、マネージドBeanを作成し、同時にJSFアプリケーションに登録できます。
マネージドBeanの作成手順:
faces-config.xmlファイルを開きます。このファイルは、<project_name>/WEB-INFディレクトリに格納されています。
ウィンドウの最下部で、「概要」タブを選択します。
左側の要素リストで、「Managed Bean」を選択します。図10-1はfaces-config.xmlファイルのJSF構成エディタを示しています。
「新規」ボタンをクリックして、図10-2のように「マネージドBeanの作成」ダイアログを開きます。Beanの名前および完全修飾クラス・パスを入力します。スコープを選択し、「Javaファイルの生成」チェック・ボックスを選択して、「OK」をクリックします。
|
ヒント: マネージドBeanがアプリケーションの複数のページで使用される場合は、スコープを「セッション」に設定する必要があります。ただし、この場合はバインディング・オブジェクトのデータがrequestスコープにあり、Beanにバインディング・コンテナへの参照を含めることができないため、このBeanはリクエストのみでしか有効になりません。バインディング・コンテナの参照が必要になる場合の例は、10.5項「宣言メソッドのオーバーライド」を参照してください。 |
必要に応じて、「管理プロパティ」バーの左にある矢印を使用して、Beanのプロパティを表示できます。「新規」をクリックしてプロパティを作成します。[F1]を押すと、構成エディタの追加のヘルプが表示されます。
|
注意: 構成エディタを使用して管理プロパティを宣言することはできますが、対応するコードはJavaクラスで生成されません。このコードを追加するため、適切なタイプのプライベート・メンバー・フィールドを作成し、コード・エディタのポップアップ・メニューの「アクセッサの生成」メニュー項目を使用してこれらのBeanプロパティに対応するgetterおよびsetterメソッドを生成する必要があります。 |
構成エディタを使用してマネージドBeanを作成し、Javaファイルの生成を選択すると、JDeveloperによって、指定された名前のスタブ・クラスおよびデフォルトのコンストラクタが作成されます。例10-1は、ビュー・パッケージに格納されるMyBeanクラスに追加されたコードを示しています。
また、JDeveloperによってmanaged-bean要素がfaces-config.xmlファイルに追加されます。この宣言により、指定された名前を参照するEL式を使用して、Beanのすべてのロジックに簡単にアクセスできるようになります。例10-2は、MyBeanクラスに対して作成されたmanaged-bean要素を示しています。
例10-2 faces-config.xmlファイルでのマネージドBeanの構成
<managed-bean> <managed-bean-name>my_bean</managed-bean-name> <managed-bean-class>view.MyBean</managed-bean-class> <managed-bean-scope>session</managed-bean-scope> </managed-bean>
この時点で、アプリケーションのページおよびメソッドによって要求されるロジックを追加する必要があります。その後、マネージドBeanに対して指定されたmanaged-bean-nameを参照するEL式を使用して、そのロジックを参照できます。たとえば、BeanのmyInfoプロパティにアクセスする場合のEL式は、次のようになります。
#{my_bean.myInfo}
この章の次の各項では、SRDemoアプリケーションのuserStateマネージドBean(view.UserSystemState.java)を使用して情報を保持または取得する場合の例を示します。マネージドBeanを使用して情報を保持する方法の詳細な例は、これらの各項を参照してください。
メソッドの戻りであるコレクションをドラッグ・アンド・ドロップしてUIコンポーネントを作成する場合は、そのメソッドによってコレクションが戻されるように、ページのレンダリング時にメソッドが実行されます。一方、メソッド自体(または別のタイプのメソッド)をドラッグし、コマンド・コンポーネントとしてドロップすると、メソッドを直接起動できます。
|
ヒント: メソッドをパラメータ・フォームとしてドロップすることもできます。詳細は、10.7.3項「カスタム・メソッドを使用した入力フォームの作成方法」および10.8項「検索ページの作成」を参照してください。 |
カスタム・メソッド以外にも、データ・コントロールには、更新オブジェクトや削除オブジェクトなどの一部の標準ビジネス・ロジックを実行する組込みメソッドが含まれる場合があります。これらのメソッドはコレクションと併用できます。たとえば、SRDemoアプリケーションには、SRPublicFacade BeanのmergeEntity(Object)メソッドが含まれており、このメソッドを使用して、任意のオブジェクトを更新してデータソース内でマージできます。
データ・コントロール・パレットからこのメソッドをドラッグしてコマンド・ボタンとしてドロップすると、ボタンが自動的にメソッドにバインドされ、ボタンをクリックするたびにメソッドが実行されるようになります。図10-3は、SRDemoアプリケーションのデータ・コントロール・パレットに表示されるメソッドの一部を示しています。
カスタム・メソッドまたは組込みメソッドのどちらでも、そのメソッドにボタンをバインドすることで、サービスBeanで関連するビジネス・ロジックを実行するコマンド・ボタンを作成できます。データ・コントロール・パレットを使用してボタンを作成すると、JDeveloperによってバインディングが自動的に作成されます。そのため、メソッドに必要なパラメータの値を設定するだけで済みます。
要求されるビジネス・ロジックを実行するために、多くのメソッドで、そのメソッドの1つ以上のパラメータに対する値が要求されます。つまり、メソッドにバインドされたボタンを作成する際には、パラメータの値が検出される場所を指定する必要があります。
たとえば、mergeEntity(Object)メソッドを使用する場合は、更新するオブジェクトを指定する必要があります。
データ・コントロール・パレットから、ページ上にメソッドをドラッグします。
|
ヒント: 表またはフォームに含まれるデータを使用するメソッドのボタンをドロップする場合は、その表またはフォームの中にボタンをドロップする必要があります。 |
ポップアップ・メニューから「メソッド」→「ADFコマンド・ボタン」を選択します。
メソッドがパラメータを取得する場合は、「アクション・バインディング・ダイアログ」が開きます。アクション・バインディング・エディタで、「パラメータ」の「値」列にある省略記号(...)ボタンをクリックし、EL式ビルダーを起動します。このビルダーを使用して、メソッドのパラメータの値を設定します。
たとえば、コレクションの更新に使用されるmergeEntity(Object)メソッドのObjectパラメータに対して値を設定する場合は、次のようにします。
EL式ビルダーでADF Bindingsノードを開き、次にbindingsノードを開きます。
JSFページのページ定義ファイルに含まれるすべてのバインディングが表示されます。
マージするオブジェクトを処理するイテレータのノードを開きます。
currentRowノードを開きます。このノードは、イテレータ内の現在の行を表します。
dataProviderプロパティを選択して、右向き矢印ボタンをクリックします。これによって、イテレータの現在の行に含まれるオブジェクトのデータに対して評価するEL式が作成されます。「OK」をクリックしてEL式ビルダーを閉じ、値にEL式を移入します。再び「OK」をクリックして、ボタンをメソッドにバインドします。
|
ヒント: パラメータ値として何を選択するかを決める際には、次のような条件を考慮します。
|
メソッドをコマンド・ボタンとしてドロップすると、JDeveloperによって次の処理が行われます。
メソッドのメソッド・アクション・バインディングが定義されます。メソッドがパラメータを取得する場合は、パラメータ値を保持するNamedData要素が作成されます。
ADF Facesコマンド・コンポーネント用のコードがJSFページに挿入されます。このコードは、その他のコマンド・ボタンのコードと同じです。詳細は、6.4.2.3項「EL式を使用したナビゲーション操作へのバインド」を参照してください。ただし、ボタンは、組込み操作用のアクション・バインディングのexecuteメソッドではなく、ドロップしたメソッド用のメソッド・アクション・バインディングのexecuteメソッドにバインドされます。
メソッドの戻りであるコレクションをドロップするときのように、パラメータを取得するメソッドをJSFページにドロップすると、JDeveloperによってメソッド・アクション・バインディングが作成されます(詳細は、6.2.2.1項「イテレータ・バインディングの作成および使用」を参照してください)。ただし、メソッドが実行するパラメータを要求する場合は、JDeveloperによって、各パラメータのNamedData要素も作成されます。これらの要素は、メソッドのパラメータを表します。
たとえば、mergeEntity(Object)メソッド・アクション・バインディングには、ObjectパラメータのNamedData要素が含まれます。この要素は、アクション・バインディングの作成時に指定した値にバインドされます。例10-3は、mergeEntity(Object)メソッドのドロップ時に作成され、Objectパラメータ(名前はentity)をfindServiceRequestByIdIterイテレータの現在の行のデータにバインドしたメソッド・アクション・バインディングを示しています。
例10-3 パラメータ・メソッドのメソッド・アクション・バインディング
<methodAction id="mergeEntity" InstanceName="SRPublicFacade.dataProvider"
DataControl="SRPublicFacade" MethodName="mergeEntity"
RequiresUpdateModel="true" Action="999"
ReturnName="SRPublicFacade.methodResults.SRPublicFacade
_dataProvider_mergeEntity_result">
<NamedData NDName="entity"
NDValue="${bindings.findServiceRequestByIdIter.
currentRow.dataProvider}"
NDType="java.lang.Object"/>
</methodAction>
ナビゲーション操作を使用してコマンド・ボタンを作成するときと同様に、メソッドを使用してコマンド・ボタンを作成すると、actionListener属性を使用して、ボタンがメソッドに自動的にバインドされます。ボタンは、指定されたメソッドのアクション・バインディングのexecuteプロパティにバインドされます。このバインディングにより、ビジネス・サービスに対してバインディングのメソッドが起動します。コマンド・ボタンのactionListener属性の詳細は、6.4.3項「実行時に行われる処理: アクション・イベントおよびアクション・リスナー」を参照してください。
|
ヒント: アクション・バインディングのexecuteメソッドにボタンをバインドするかわりに、executeメソッドをオーバーライドするバッキングBean内のメソッドにボタンをバインドできます。そうすることで、元のメソッドの実行前か実行後に、ロジックを追加できるようになります。詳細は、10.5項「宣言メソッドのオーバーライド」を参照してください。 |
ナビゲーション操作のように、ボタンのdisabledプロパティは、EL式を使用してボタンを表示するかどうかを決定します。例10-4は、コマンド・ボタンをmergeEntity(Object)メソッドにバインドするためのEL式を示しています。
1つのページでのアクションに対して、別のページにデータを表示するメソッドなどにパラメータを設定しなければならない場合があります。図10-4のように、SRDemoアプリケーションのSRListページでは、ユーザーがクリックすると直接サービス・リクエストを編集できる、コマンド・リンクが使用されています。
commandLinkコンポーネントは、SREditページへの移動、およびSREditページにデータを表示するフォームを作成するためのfindServiceRequestById(Integer)メソッドに必要なパラメータの設定の両方に使用されます。ADF FacesのsetActionListenerコンポーネントを使用して、パラメータを設定できます。
|
ヒント: SRDemoアプリケーションのこのページではsetActionListenerコンポーネントは使用されていません。SREditページに対してこのパラメータを設定するために、複数のページで同じロジックが要求されるため、かわりに、マネージドBeanのメソッドによって、これと同じ機能が提供されます。1つのページで必要とされるロジックが他のページでも必要とされる場合は、そのロジックをマネージドBeanに配置する方が効果的な場合があります。マネージドBeanの使用方法の詳細は、10.2項「マネージドBeanを使用した情報の格納」を参照してください。 |
setActionListenerコンポーネントを使用して、他のオブジェクトに値を設定できます。このコンポーネントは、コマンド・コンポーネントの子である必要があります。
setActionListenerコンポーネントの使用手順:
データ・コントロール・パレットまたはコンポーネント・パレットを使用して、コマンド・コンポーネントを作成します。
コンポーネント・パレットからsetActionListenerコンポーネントをドラッグして、コマンド・コンポーネントの子としてドロップします。
「至」にパラメータ値の設定場所を設定します。
|
ヒント: 作成されるページのページ定義ファイルに直接パラメータ値を設定するかわりに、マネージドBeanまたはスコープにパラメータ値を格納することを考慮してください。次のページに直接設定すると、それ以降、ナビゲーションを簡単に変更できなくなります。詳細は、10.2項「マネージドBeanを使用した情報の格納」を参照してください。また、バインディング・コンテナ内のデータは、そのコンテナが準備されたリクエストでのみ有効です。そのため、データを設定してから次のページがレンダリングされるまでの間に、データが変更される場合があります。 |
パラメータ値が別のページのパラメータ付きフォームを作成するためのメソッドで必要とされる場合、フォームを作成するときに、パラメータに手順4の「至」属性の値を設定します。詳細は、10.6項「パラメータを取得するメソッドを使用したフォームまたは表の作成」を参照してください。
setActionListenerコンポーネントを使用すると、移動する前にコマンド・コンポーネントによって値が設定されます。From属性を渡す値のソースに設定すると、コンポーネントからその値へのアクセスが可能になります。To属性をターゲットに設定すると、コマンド・コンポーネントによってターゲットに値が設定されるようになります。例10-5は、JSFページのコマンド・リンクのコードを示しています。このコマンド・リンクは、現在の行のデータにfrom値としてアクセスし、To属性を使用してデータをマネージドBeanの属性の値として設定します。
例10-5 setActionListenerコンポーネントを使用したコマンド・リンクのJSFページ・コード
<af:commandLink actionListener="#{bindings.setCurrentRowWithKey.execute}"
action="edit"
text="#{row.svrId}"
disabled="#{!bindings.setCurrentRowWithKey.enabled}"
id="commandLink1">
<af:setActionListener from="#{row.svrId}"
to="#{userState.currentSvrId}"/>
</af:commandLink>
ユーザーがコマンド・コンポーネントをクリックすると、移動する前に、setActionListenerコンポーネントによってパラメータ値が設定されます。例10-5では、setActionListenerによって現在の行のsvrId属性が取得され、その値がuserStateマネージドBeanのcurrentSvrId属性の値として設定されます。これにより、このページの現在の行のsvrIdを必要とするすべてのメソッドは、EL式#{userState.currentSvrId}を使用してこれにアクセスできます。
たとえば、findServiceRequestById(Integer)メソッドをドロップしてSREditページのフォームを作成する場合は、Integerパラメータの値として#{userState.currentSvrId}を入力します。詳細は、10.6項「パラメータを取得するメソッドを使用したフォームまたは表の作成」を参照してください。
メソッドをコマンド・ボタンとしてドロップすると、関連付けられているバインディング・オブジェクトのexecuteメソッドに、そのボタンが自動的にバインドされます。このバインディングにより、関連するバインディング・コードを記述せずに、JSFページを宣言的に作成できるようになります。ただし、メソッドの実行前または実行後に、ロジックの追加が必要になる場合もあります。たとえば、表の複数の行を選択して削除するには、各行にアクセスして現在の行にするコードを、削除メソッドの実行前に追加する必要があります。詳細は、7.6.4項「selectionファセットにおけるtableSelectManyコンポーネントの使用方法」を参照してください。
JDeveloperでは、関連付けられているアクション・バインディングへのアクセスを提供するマネージドBeanの新規メソッドおよびプロパティを作成して、宣言メソッドにロジックを追加できます。デフォルトでは、この生成されたコードによって、対応するバインディングのメソッドが実行されます。その後、このコードの前か後にロジックを追加できます。バインディングのexecuteプロパティではなく、この新規メソッドに、JDeveloperによってコマンド・コンポーネントが自動的にバインドされます。その後、ユーザーがボタンをクリックすると、新規メソッドが実行されます。
次に、BeanSRDemoアプリケーションの一部の例を示します。それぞれの例では、まずバインディング・コンテナを挿入し、宣言メソッドの実行前または実行後にロジックを追加するメソッドが、バッキングBeanに含まれています。
SRCreateConfirm.java: createSR_actionメソッドは、createServiceRequestメソッドをオーバーライドしてメソッドの実行前に検証ロジックを追加し、メソッドの実行後にパラメータ値を設定します。
SRMain.java: deleteSR_actionメソッドは、removeServiceRequestメソッドをオーバーライドし、削除を実行する前に、サービス・リクエストに関連付けられている履歴があるかどうかをチェックします。srDelete_actionメソッドは、サービス履歴表の複数の行を削除するために、removeServiceHistoryメソッドをオーバーライドします。
宣言メソッドをオーバーライドするには、マネージドBeanにコマンド・コンポーネントがバインドされる新規メソッドを保持させる必要があります。ページにバッキングBeanが関連付けられている場合は、JDeveloperによって、バインディング・オブジェクトへのアクセスに必要なコードがバッキングBeanに追加されます。ページにバッキングBeanが関連付けられていない場合は、作成を促す指示が表示されます。
|
注意: 現在、コマンド・コンポーネントのAction属性の値としてEL式が設定されている場合は、JDeveloperによってEL式が上書きされないため、次の手順を使用できません。次の手順を行う前に、この値を削除する必要があります。 |
宣言メソッドのオーバーライドの手順:
オーバーライドするメソッドをJSFページ上にドラッグし、UIコマンド・コンポーネントとしてドロップします。
これにより、コンポーネントが作成され、コンポーネントのActionListener属性を使用して、ADFモデル・レイヤーの関連するバインディング・オブジェクトにバインドされます。
データ・コントロール・パレットのメソッドを使用したコマンド・コンポーネントの作成方法の詳細は、10.3項「メソッドを実行するためのコマンド・コンポーネントの作成」を参照してください。
JSFページでコンポーネントをダブルクリックします。
「バインドActionプロパティ」ダイアログで、バッキングBeanおよびコンポーネントをバインドするメソッドを指定します。指定方法は次のいずれかです。
自動バインディングがそのページで有効化されている場合は、図10-5のように、バッキングBeanはすでに自動選択されています。
新規メソッドを作成するには、「メソッド」フィールドにメソッドの名前を入力します。このフィールドには、最初にデフォルト名が表示されています。
または
既存のメソッドを使用するには、「メソッド」フィールドのドロップダウン・リストからメソッドを選択します。
「ADFバインディング・コードの生成」を選択します。
そのページで自動バインディングが使用されていない場合は、図10-6のように、既存のバッキングBeanから選択するか、新たに作成できます。自動バインディングの詳細は、4.5.4項「自動コンポーネント・バインディング機能の使用方法」を参照してください。
「新規」をクリックして、新しいバッキングBeanを作成します。「マネージドBeanの作成」ダイアログが表示されます。このダイアログを使用して、Beanおよびクラスに名前を付け、Beanのスコープを設定します。
または
既存のバッキングBeanおよびメソッドをドロップダウン・リストから選択します。
バッキングBeanおよびメソッドを識別したら、「バインドActionプロパティ」ダイアログで「OK」をクリックします。
ソース・エディタでマネージドBeanが自動的に開きます。例10-6は、Beanに挿入されたコードを示しています。この例では、コマンド・ボタンがmergeEntityメソッドにバインドされます。
例10-6 バインディング・オブジェクトへのアクセス用にバッキングBeanで生成されたコード
public BindingContainer getBindings() {
return this.bindings;
}
public void setBindings(BindingContainer bindings) {
this.bindings = bindings;
}
public String commandButton_action1() {
BindingContainer bindings = getBindings();
OperationBinding operationBinding =
bindings.getOperationBinding("mergeEntity");
Object result = operationBinding.execute();
if (!operationBinding.getErrors().isEmpty()) {
return null;
}
return null;
}
バインディング・オブジェクトにアクセスする前または後に、ロジックを追加できます。
FacesContext fc = FacesContext.getCurrentInstance();
ValueBinding expr =
fc.getApplication().
createValueBinding("#{bindings.SomeAttrBinding.inputValue}");
DCIteratorBinding ib = (DCIteratorBinding)
expr.getValue(fc);
処理ロジックに加えて条件付きロジックを記述して、特定の条件に基づいて複数の結果の中から1つを戻すことができます。たとえば、処理中にエラーが発生した場合にはnullを、処理が正常終了した場合は別の結果値を戻すことができます。nullの戻り値により、ナビゲーション・ハンドラはナビゲーション・ケースを評価せずに、そのまま現在ページを再表示します。
|
ヒント: 特定のナビゲーション・ケースをトリガーするには、メソッドによって戻される結果値が、ナビゲーション・ルールの結果値と大/小文字の区別も含めて完全に一致する必要があります。 |
この時点で、コマンド・ボタンは、ActionListener属性ではなく、Action属性を使用して新しいメソッドにバインドされています。Action属性の値(結果文字列など)がすでに存在していた場合は、その値が新規メソッドの戻りとして追加されます。値が存在していなかった場合は、戻りがnullのままになります。
宣言メソッドをオーバーライドすると、#{bindings}(バインディング・コンテナへの参照)の管理プロパティ値を使用してバッキングBeanに管理プロパティが追加され、強く型付けされたBeanプロパティがBindingContainer型のクラスに追加されます。このプロパティは、JSFランタイムによって管理プロパティ式#{bindings}の値を使用して設定されます。また、JDeveloperによって、UIコマンド・アクション・メソッドにもロジックが追加されます。このロジックには、現在のバインディング・コンテナにアクセスするための、強く型付けされたgetBindings()メソッドが含まれます。
例10-8は、選択したマネージドBeanに自動的に追加されたコードを示しています。戻りのString "back"は、メソッドに自動的に追加されたものです。
例10-8 バインディング・オブジェクトへのアクセス用にバッキングBeanで生成されたコード
private BindingContainer bindings;
...
public String commandButton1_action() {
BindingContainer bindings = getBindings();
OperationBinding operationBinding =
bindings.getOperationBinding("mergeEntity");
Object result = operationBinding.execute();
if (!operationBinding.getErrors().isEmpty()) {
return null;
}
return "back";
}
ActionListener属性ではなく、Action属性を使用して新しいメソッドにUIコマンド・コンポーネントがリバインドされます。たとえば、例10-9は、mergeEntityメソッドをドロップして作成されたコマンド・ボタンに対する、JSFページのコードを示しています。actionListener属性はmergeEntityメソッドにバインドされており、action属性にはbackのString結果が含まれます。ユーザーがボタンをクリックすると、メソッドが単純に実行され、このナビゲーション・ケースのtoViewIdとして定義されているページに移動します。
例10-9 宣言メソッドにバインドされたコマンド・ボタンのJSFページ・コード
<af:commandButton actionListener="#{bindings.mergeEntity.execute}"
text="persistEntity"
disabled="#{!bindings.persistEntity.enabled}"
id="commandButton1"
action="back"/>
例10-10は、ページのバッキングBeanのメソッドをオーバーライドした後のコードを示しています。ここでは、action属性は、バッキングBeanのメソッドにバインドされています。
例10-10 オーバーライド後のメソッドにバインドされたコマンド・ボタンのJSFページ・コード
<af:commandButton text="persistEntity"
disabled="#{!bindings.mergeEntity.enabled}"
binding="#{backing_create.commandButton1}"
id="commandButton1"
action="#{backing_create.commandButton1_action}"/>
このコードによって行われる処理は次のとおりです。
関連付けられているメソッドのバインディングを検索し、実行します。
ナビゲーションに使用できるメソッドの戻りを追加します。デフォルトでは戻りはnullですが、ボタンのAction属性にすでに結果文字列が存在する場合は、その属性が戻り値として使用されます。このコードは、必要に応じて変更できます。戻された結果の使用方法の詳細は、9.4項「動的ナビゲーションの使用」を参照してください。
|
ヒント: オーバーライド済メソッドを使用するボタンをクリックすると、次のエラーが表示されます。
これは、オーバーライドするメソッドを含むマネージドBeanのスコープが、 |
フォームまたは表に内容を表示するために、情報の取得が必要になる場合があります。このようなページについては、パラメータを取得するメソッドから戻されたコレクションを使用して、フォームまたは表を作成します。パラメータ値は、別のページまたはメソッドにより設定されます。
たとえば、SREditページのフォームは、findServiceRequestsById(Integer)メソッドから戻されたコレクションを使用して作成されています。戻されるのは、すべてのサービス・リクエストではなく、ユーザーが前のページで選択したサービス・リクエストのみです。前のページのコマンド・リンクは、パラメータ(Integer)を設定します。このパラメータは、サービス・リクエストのIDを提供します。コマンド・コンポーネントを使用したパラメータ値の設定の詳細は、10.4項「コマンド・コンポーネントを使用したパラメータ値の設定」を参照してください。
パラメータを要求するフォームまたは表を作成するには、戻すレコードを判別するために、パラメータの値へのアクセスが必要になります。たとえば、フォームまたは表を作成する前に、一部のオブジェクトのパラメータ値を設定する別のページのコマンド・ボタンにロジックを追加して、そのオブジェクトにメソッドがアクセスできるようにすることが必要になる場合があります。詳細は、10.4項「コマンド・コンポーネントを使用したパラメータ値の設定」を参照してください。この処理が終了したら、フォームまたは表のパラメータ値を設定できます。
1つまたは複数のパラメータを取得するメソッドの戻りであるコレクションをデータ・コントロール・パレットからドラッグし、いずれかのタイプのフォームまたは表としてドロップします。
「フォーム・フィールドの編集」ダイアログまたは「表の列の編集」ダイアログで、必要に応じてフォームまたは表を構成し、「OK」をクリックします。
これらのダイアログの使用方法を表示するには、「ヘルプ」をクリックします。
メソッドによってパラメータが取得されるため、アクション・バインディング・エディタが開き、パラメータ値を設定するよう求められます。
アクション・バインディング・エディタの「値」フィールドの省略記号(...)ボタンをクリックしてEL式ビルダーを開き、各パラメータの値を入力します。パラメータの値を表すノードを選択します。
たとえば、例10-5「setActionListenerコンポーネントを使用したコマンド・リンクのJSFページ・コード」では、setActionListenerComponentによって、userStateBeanのsvrIdパラメータ値がcurrentSvrId属性として設定されています。この値にアクセスするには、パラメータの値として#{userState.currentSvrId}を使用します。
アクション・バインディング・エディタは、この値を使用して、メソッドの実行時にパラメータを表すNamedData要素を作成します。コマンド・ボタンにバインドされたメソッドとは異なり、メソッドの戻りであるコレクションをドロップしているため、関連付けられているイテレータがページのロードとともに実行されると、このメソッドが実行されます。パラメータ値の設定は、ページがレンダリングされる前に行います。つまり、NamedData要素は、送る側のページによって値が設定された場所から値を取得する必要があります。
パラメータを取得するメソッドの戻りを使用してフォームを作成すると、JDeveloperによって次の処理が行われます。
メソッドのアクション・バインディング、メソッドの結果のメソッド・イテレータ・バインディング、およびオブジェクトの各属性の属性バインディングが作成されるか、表の場合は表バインディングが作成されます。メソッドによって要求される各パラメータのNamedData要素も作成されます。
ADF Facesコマンド・コンポーネントを使用して、JSFページにフォームのコードが挿入されます。
例10-11は、findServiceRequestsById(Integer)メソッドをドロップしたときに作成されるアクション・メソッド・バインディングを示しています。この例では、findSvrIdの値がUserStateマネージドBeanのcurrentSvrId属性に設定されています。
例10-11 メソッド戻りのメソッド・アクション・バインディング
<bindings>
<methodAction id="findServiceHistoryById"
InstanceName="SRPublicFacade.dataProvider"
DataControl="SRPublicFacade"
MethodName="findServiceHistoryById" RequiresUpdateModel="true"
Action="999"
ReturnName="SRPublicFacade.methodResults.SRPublicFacade_
dataProvider_findServiceHistoryById_result">
<NamedData NDName="svrIdParam" NDValue="${userState.currentSvrId}"
NDType="java.lang.Integer"/>
</methodAction>
...
</bindings>
NamedData要素は、要求側のページで設定されたように、userState Beanの現在のサービス・リクエストIDに対して評価します。
ユーザーがコマンド・ボタンをクリックしたときに実行されるメソッドとは異なり、フォームの作成に使用されるメソッドは、ページがロードされるときに実行されます。ページに対してデータを戻すためにメソッドが実行されると、メソッドはNamedData要素のEL式を評価し、その値をパラメータとして使用します。その後、メソッドは正しいデータを戻すことができます。メソッドが複数のパラメータを取得する場合は、パラメータごとに評価が行われ、メソッドのパラメータが設定されます。
たとえば、SREditページのロード時には、userStateマネージドBeanのcurrentSvrIdフィールドの値が使用され、findServiceRequestsById(Integer)メソッドによって要求されるパラメータの値として設定されます。メソッドが実行されると、パラメータの値と一致するレコードのみが戻されます。フォームを作成するためにメソッドの戻りをドロップしたため、戻りは表示されるサービス・リクエストになります。
ユーザーが新規レコードの情報を入力し、そのレコードをデータソースにコミットするためのフォームを作成できます。データ・コントロールのセッションBeanが作成されると、デフォルトで、データ・コントロールのオブジェクトに対するコンストラクタ・メソッドが作成されます。たとえば、SRDemoアプリケーションのSRPublicFacadeセッションBeanには、製品、専門分野、サービス履歴、ユーザーおよびサービス・リクエストのコンストラクタ・メソッドがあります。コンストラクタは、メソッドに渡せるオブジェクトを宣言的に作成する方法を提供します。たとえば、セッションBeanにデフォルトで含まれているpersistEntity(Object) CRUDメソッドを使用すると、新規レコードをデータベースに保存できます(デフォルトのセッションBeanメソッドに関する詳細は、3.2.1.2項「セッション・ファサード・メソッドの生成」を参照してください)。コンストラクタ・メソッドを使用して入力フォームを作成する場合は、オブジェクトを作成し、オブジェクトの変数を入力された値に初期化するために、メソッドがコールされます。その後、データソースで新規レコードを作成するpersistEntityメソッドに、コンストラクタの結果を簡単に渡すことができます。
ただし、場合によっては、新規オブジェクトの作成方法をより詳細に制御する必要があります。たとえば、特定の属性に値をプログラム的に移入するとします。この場合、オブジェクトの作成を処理するカスタム・メソッドを作成できます。
カスタム・メソッドを使用して入力フォームを作成するには、メソッドから戻されたコレクションをドロップするかわりに、メソッド自体をパラメータ・フォームとしてドロップします。メソッドにバインドされたコマンド・ボタンがJDeveloperによって自動的に追加され、ユーザーがこのボタンをクリックすると、作成したカスタムメソッドが実行されます。
たとえば、SRDemoアプリケーションのSRPublicFacadeデータ・コントロールには、createServiceRequest(String, Integer, Integer)メソッドが含まれています。Stringは問題の説明の値、Integerは製品ID、2つ目のIntegerはリクエストを作成したユーザーのIDをそれぞれ表します。このメソッドにより、オブジェクトの属性に移入するパラメータの値を使用して、ServiceRequestオブジェクトの新規インスタンスが作成されます。製品IDおよびユーザーのIDは、ユーザーではなくメソッドによって設定されます。
データ・コントロールのコンストラクタは、そのデータ・コントロールの「コンストラクタ」フォルダにあります。コンストラクタは、オブジェクトの作成に使用されるデータ・コントロールのデフォルト・メソッドにアクセスします(詳細は、3.2.1.2項「セッション・ファサード・メソッドの生成」を参照してください)。図10-7は、SRPublicFacadeデータ・コントロールのコンストラクタを示しています。
コンストラクタを使用した入力フォームの作成手順:
データ・コントロール・パレットから、JSFページ上に適切なコンストラクタをドラッグします。コンストラクタはフォームとしてのみドロップできるため、ポップアップ・メニューは表示されません。
「フォーム・フィールドの編集」ダイアログで、ラベル、バインディングおよびUIコンポーネントを設定します。「送信ボタンを含める」は選択しないでください。
データ・コントロール・パレットから、persistEntity(Object)メソッドをドラッグします。このメソッドは、コンストラクタによって作成されたオブジェクトをデータベースに保存します。
ポップアップ・メニューから「メソッド」→「ADFコマンド・ボタン」を選択します。
アクション・バインディング・エディタの「値」フィールドにある省略記号(...)ボタンをクリックしてEL式ビルダーを起動し、entityパラメータの値を入力します。ここではentityパラメータをコンストラクタの結果にするために、図10-8のように、コンストラクタのアクション・バインディングの下にある「結果」を選択します。
コンストラクタを使用して入力フォームを作成すると、JDeveloperによって次の処理が行われます。
コンストラクタ・メソッドのアクション・バインディング、コンストラクタ・メソッドの結果のメソッド・イテレータ・バインディング、およびオブジェクトの各属性の属性バインディングが作成されます。また、実行可能バインディングに起動アクションが作成され、このアクションによって、このコンストラクタ・メソッドがモデルのレンダリング・フェーズで実行されます。
ADF Faces inputTextコンポーネントを使用して、JSFページにフォームのコードが挿入されます。
たとえば、SRDemoで製品の単純な入力フォームを作成するには、図10-9のように、データ・コントロール・パレットから製品コンストラクタ・メソッドをパラメータ・フォームとしてドロップし、そのフォームの下に、persistEntityメソッドをボタンとしてドロップできます。
|
注意: この例で示したページは、実際のSRDemoアプリケーションには含まれていません。 |
例10-12は、この入力フォームのページ定義ファイルを示しています。起動アクション・バインディングが実行されると、アクション・バインディングを使用してコンストラクタ・メソッドがコールされます。その後、コンストラクタ・メソッドの結果が、イテレータにバインドされます。persistEntity(Object)メソッドをコマンド・ボタンとしてドロップすると、メソッドがイテレータを介してコンストラクタの結果にアクセスできるようになります。
例10-12 コンストラクタのページ定義コード
<executables>
<invokeAction Binds="Product" id="invokeProduct" Refresh="renderModel"
RefreshCondition="${!adfFacesContext.postback and empty
bindings.exceptionsList}"/>
<methodIterator DataControl="SRPublicFacade"
BeanClass="oracle.srdemo.model.entities.Product"
Binds="Product.result" id="ProductIter"
Refresh="renderModel"
RefreshCondition="${!adfFacesContext.postback and empty
bindings.exceptionsList}"/>
</executables>
<bindings>
<methodAction DataControl="SRPublicFacade" id="Product" MethodName="Product"
RequiresUpdateModel="true" Action="999"
ReturnName="SRPublicFacade.methodResults.SRPublicFacade_
Product_result"
ClassName="oracle.srdemo.model.entities.Product"/>
<attributeValues id="description" IterBinding="ProductIter">
<AttrNames>
<Item Value="description"/>
</AttrNames>
</attributeValues>
<attributeValues id="image" IterBinding="ProductIter">
<AttrNames>
<Item Value="image"/>
</AttrNames>
</attributeValues>
<attributeValues id="name" IterBinding="ProductIter">
<AttrNames>
<Item Value="name"/>
</AttrNames>
</attributeValues>
<attributeValues id="prodId" IterBinding="ProductIter">
<AttrNames>
<Item Value="prodId"/>
</AttrNames>
</attributeValues>
<methodAction id="persistEntity" InstanceName="SRPublicFacade.dataProvider"
DataControl="SRPublicFacade" MethodName="persistEntity"
RequiresUpdateModel="true" Action="999"
ReturnName="SRPublicFacade.methodResults.SRPublicFacade_
dataProvider_persistEntity_result">
<NamedData NDName="entity" NDValue="${bindings.Product.result}"
NDType="java.lang.Object"/>
</methodAction>
</bindings>
コンストラクタ・メソッドが起動されると、必ずオブジェクトが作成されます。ただし、データがキャッシュされ、それによってメソッドによるサーバーへのポストバックが可能になるため、ユーザーが別のオブジェクトを作成するなどの目的でページに再びアクセスすると、コンストラクタ・メソッドによって同じオブジェクトが再び作成されます。また、エラーが発生すると、エラー・メッセージを使用してページが再レンダリングされるため、オブジェクトが再び作成されます。
複製を回避するために、起動アクションのrefreshConditionプロパティは、サーバーへのポストバックが存在せず、エラー・メッセージがないかぎり、コンストラクタが1回しか起動されないように設定されています。EL式は例10-12を参照してください。
イテレータのリフレッシュ条件は同じです。この設定により、ユーザーがページに再アクセスしたときに、ポストバックで使用されたキャッシュ・データがイテレータによって表示されなくなり、かわりに、データが含まれていないフォームが表示されます。
カスタム・メソッドを使用して入力フォームを作成する場合は、ユーザーによって移入されるデータを使用できるメソッドをドラッグし、パラメータ・フォームとしてドロップします。この場合は、オブジェクトを作成する必要があるため、戻りをドロップすることはできません。メソッド自体をドロップします。
カスタム・メソッドを使用した入力フォームの作成手順:
データ・コントロール・パレットから、JSFページ上に適切なメソッドをドラッグします。
ポップアップ・メニューから、「パラメータ」→「ADFパラメータ・フォーム」を選択します。
「フォーム・フィールドの編集」ダイアログが開きます。このダイアログでラベル、バインディングおよびUIコンポーネントをカスタマイズしてから、フォームを作成できます。JDeveloperによって、メソッドにバインドされたコマンド・ボタンが自動的に追加されます。
メソッドをパラメータ・フォームとしてドロップすると、JDeveloperによって次の処理が行われます。
データ値を保持する変数、メソッドのメソッド・バインディング、および関連付けられている属性の属性バインディングが、ページ定義ファイルで定義されます。
ADF Faces inputTextコンポーネントおよびADF Facesコマンド・ボタン・コンポーネントを使用して、JSFページにフォームのコードが挿入されます。このコードは、その他の入力フォームまたはコマンド・ボタンのコードと同じです。
パラメータを取得するメソッドの戻りであるコレクションをドロップした場合と同様に、JSFページ上にメソッド自体をドロップすると、JDeveloperによって各パラメータのNamedData要素が作成されます。ただし、10.6項「パラメータを取得するメソッドを使用したフォームまたは表の作成」のように別のページで値が提供されるのとは異なり、ユーザーがパラメータ値を指定するため、各NamedData要素は、対応する属性の属性バインディングにバインドされます。
このバインディングにより、メソッドは、実行のパラメータに対する正しい属性の値にアクセスできます。
たとえば、createServiceRequestメソッド・アクション・バインディングには、使用する各パラメータのNamedData要素が含まれます。そして、NamedData要素は、EL式を使用して、対応する属性バインディングにバインドされます。例10-13は、メソッド・アクション・バインディングおよび createServiceRequestメソッドのドロップ時に作成される属性バインディングの一部を示しています。
例10-13 ページ定義ファイルでのメソッド・アクション・バインディング
<bindings>
<methodAction id="createServiceRequest" MethodName="createServiceRequest"
RequiresUpdateModel="true" Action="999"
DataControl="SRPublicFacade"
InstanceName="SRPublicFacade.dataProvider"
ReturnName="SRPublicFacade.methodResults.SRPublicFacade_
dataProvider_createServiceRequest_result">
<NamedData NDName="problemDescription" NDType="java.lang.String"
NDValue="${bindings.createServiceRequest_problemDescription}"/>
<NamedData NDName="productId" NDType="java.lang.Integer"
NDValue="${bindings.createServiceRequest_productId}"/>
<NamedData NDName="createdBy" NDType="java.lang.Integer"
NDValue="${bindings.createServiceRequest_createdBy}"/>
</methodAction>
<attributeValues id="problemDescription" IterBinding="variables">
<AttrNames>
<Item Value="createServiceRequest_problemDescription"/>
</AttrNames>
</attributeValues>
<attributeValues id="productId" IterBinding="variables">
<AttrNames>
<Item Value="createServiceRequest_productId"/>
</AttrNames>
...
</attributeValues>
</bindings>
コレクションの属性と同じように、メソッドの属性もイテレータを参照します。ただし、関連付けられているメソッドが戻すコレクションにアクセスして反復処理を行うメソッド・イテレータを参照するのではなく、作成タイプのメソッドの属性は、変数にアクセスして反復処理を行います。このタイプのメソッドではまだオブジェクトが戻されていないため、ページに入力された値を保持するものはありません。変数はデータ・ホルダーとして機能します。
JDeveloperによって、メソッドが取得する各パラメータの変数が作成されます。変数は変数イテレータの子として宣言され、ローカルであるため、関連付けられているバインディング・コンテキストのみで有効になります。例10-14は、createServiceRequest(String, Integer, Integer)メソッドの使用時に作成される変数イテレータおよび変数を示しています。
例10-14 ページ定義ファイルでの変数イテレータおよび変数
<executables>
<variableIterator id="variables">
<variable Type="java.lang.String"
Name="createServiceRequest_problemDescription"
IsQueriable="false"/>
<variable Type="java.lang.Integer" Name="createServiceRequest_productId"
IsQueriable="false"/>
<variable Type="java.lang.Integer" Name="createServiceRequest_createdBy"
IsQueriable="false"/>
</variableIterator>
</executables>
ユーザーがデータを入力してフォームを送信すると、変数に値が移入され、NamedData要素の値に対するEL式を使用して、属性バインディングによってメソッドのパラメータの値が提供されるようになります。
SRDemoアプリケーションのサービス・リクエスト作成プロセスでは、プロセス・トレインが使用され、これによって実際のリクエストの作成が3つの手順に分割されます(11.5項「複数ページ・プロセスの作成」を参照してください)。説明の便宜上、ここではプロセスが1つのページに含まれていると仮定します。対応するinputTextコンポーネントにユーザーが説明を入力し、Create Productボタンをクリックすると、次の処理が実行されます。
problemDescriptionVar変数にユーザーが入力した値が移入されます。
problemDescription属性バインディングが変数イテレータを参照し、特にItem値としてproblemDescriptionVar変数を参照するため、次のように、属性バインディングによって説明が取得されます。
<attributeValues id="problemDescription" IterBinding="variables">
<AttrNames>
<Item Value="createServiceRequest_problemDescription"/>
</AttrNames>
</attributeValues>
次のように、NamedData要素のNameには、problemDescription属性バインディングのアイテム値に対して評価するEL式が含まれているため、値にもアクセスできます。
<NamedData NDName="problemDescription" NDType="java.lang.String" NDValue="${bindings.createServiceRequest_problemDescription}"/>
createServiceRequestメソッドは、対応するNamedData要素から値を取得する各パラメータを使用して実行されます。
パラメータを取得してレコードを検索するメソッドを使用して、検索フォームを作成できます。また、その結果を表に表示できます。このタイプの検索フォームでは、ユーザーが各パラメータの情報を入力する必要があります。図10-10は、ID、ステータスおよび問題の説明を指定してすべてのサービス・リクエストを検索できる、SRSearch検索フォームを示しています。
検索するロジックを含む既存のメソッドをドロップして検索フォームを作成し、パラメータに基づいてレコードを戻すことができます。このメソッドは、データ・コントロールにすでに存在している必要があります。図10-11は、図10-10に示した検索フォームの作成に使用する、findServiceRequestSearch(Integer, String, String)メソッドを示しています。ID、ステータスおよび説明を指定すると、このメソッドにより、すべてのサービス・リクエストが検索され、戻されます。
検索フォームを作成するには、メソッドをパラメータ・フォームとしてドロップします。その後、戻されたコレクションを表としてドロップし、結果を表示します。セッション中にユーザーが初めてSRSearchページにアクセスしたときには、このページに結果表は表示されません。条件付きで結果表を非表示にする手順は、10.9項「検索ページの結果表の条件付き表示」を参照してください。
検索フォームおよび結果表の作成手順:
データ・コントロール・パレットからパラメータを取得する検索メソッドをドラッグします。
ポップアップ・メニューから、「パラメータ」→「ADFパラメータ・フォーム」を選択します。
データ・コントロール・パレットからメソッドの戻りをドラッグし、いずれかのタイプの表としてドロップします。
メソッドをパラメータ・フォームとしてドロップすると、JDeveloperによって次の処理が行われます。
データ値を保持する変数、メソッドのメソッド・バインディング、および関連付けられている属性の属性バインディングが、ページ定義ファイルで定義されます。
ADF Faces inputTextコンポーネントおよびADF Faces commandButtonコンポーネントを使用して、JSFページにフォームのコードが挿入されます。このコードは、その他の入力フォームまたはコマンド・ボタンのコードと同じです。
メソッドの戻りであるコレクションをドロップする場合と同様に、パラメータを取得するメソッドをJSFページ上にドロップすると、JDeveloperによってメソッド・アクション・バインディングが作成されます。ただし、実行するパラメータがメソッドによって要求されるため、JDeveloperによって、各パラメータのNamedData要素も作成されます。これらの要素は、メソッドのパラメータを表します。各要素は、対応する属性の値バインディングにバインドされます。このバインディングにより、メソッドは、実行のパラメータに対する正しい属性の値にアクセスできます。
たとえば、findServiceRequestSearchメソッド・アクション・バインディングには、取得する各パラメータのNamedData要素が含まれます。NamedData要素のstatusParamは、EL式を使用して、findServiceRequestSearch_statusParam属性バインディングにバインドされます。例10-15は、メソッド・アクション・バインディングおよびfindServiceRequestSearchメソッドをパラメータ・フォームとしてドロップしたときに作成される属性バインディングの一部を示しています。
例10-15 ページ定義ファイルでのメソッド・アクション・バインディング
<bindings>
<methodAction id="findServiceRequestSearch"
MethodName="findServiceRequestSearch"
RequiresUpdateModel="true" Action="999"
DataControl="SRPublicFacade"
InstanceName="SRPublicFacade.dataProvider"
ReturnName="SRPublicFacade.methodResults.SRPublicFacade_
dataProvider_findServiceRequestSearch_result">
<NamedData NDName="svrIdParam" NDType="java.lang.Integer"
NDValue="${bindings.findServiceRequestSearch_svrIdParam}"/>
<NamedData NDName="statusParam" NDType="java.lang.String"
NDValue="${bindings.findServiceRequestSearch_statusParam}"/>
<NamedData NDName="problemParam" NDType="java.lang.String"
NDValue="${bindings.findServiceRequestSearch_problemParam}"/>
</methodAction>
...
<attributeValues id="svrIdParam" IterBinding="variables">
<AttrNames>
<Item Value="findServiceRequestSearch_svrIdParam"/>
</AttrNames>
</attributeValues>
<attributeValues id="problemParam" IterBinding="variables">
<AttrNames>
<Item Value="findServiceRequestSearch_problemParam"/>
</AttrNames>
</attributeValues>
...
</bindings>
戻りではなくメソッドをドロップしたため、属性によって、コレクションにアクセスして反復処理を行うメソッド・イテレータではなく、変数にアクセスして反復処理を行う変数イテレータが参照されます。これは、メソッドは(戻されたコレクションとは異なり)オブジェクトのインスタンスにアクセスする必要がなく、ページに入力された値を保持するものがないためです。変数はこれらのデータ・ホルダーとして機能します。
JDeveloperによって、各メソッド・パラメータの変数が作成されます。変数は変数イテレータの子として宣言され、ローカルであるため、関連付けられているバインディング・コンテキストのみで有効になります。例10-16は、変数イテレータおよびfindServiceRequestSearchメソッドの使用時に作成される変数を示しています。変数イテレータは、フォームおよびボタンの両方で使用されます。
例10-16 ページ定義ファイルでの変数イテレータおよび変数
<executables>
<variableIterator id="variables">
<variable Type="java.lang.Integer"
Name="findServiceRequestSearch_svrIdParam" IsQueriable="false"/>
<variable Type="java.lang.String"
Name="findServiceRequestSearch_statusParam"
IsQueriable="false"/>
<variable Type="java.lang.String"
Name="findServiceRequestSearch_problemParam"
IsQueriable="false"/>
</variableIterator>
...
</executables>
その後、戻されたコレクションを結果表用にドロップすると、JDeveloperによって、戻されたコレクションを反復処理するメソッド・イテレータが追加されます。結果は表に含まれるため、表バインディングも作成されます。例10-17は、メソッド・イテレータおよび表バインディングに対して生成されたコードを示しています。
例10-17 戻されたコレクションのページ定義コード
<executables>
<variableIterator id="variables">
...
</variableIterator>
<methodIterator id="findServiceRequestSearchIter"
Binds="findServiceRequestSearch.result"
DataControl="SRPublicFacade" RangeSize="10"
BeanClass="oracle.srdemo.model.entities.ServiceRequest"/>
</executables>
<bindings>
...
<table id="findAllServiceRequest1" IterBinding="resultsIterator">
<AttrNames>
<Item Value="assignedDate"/>
<Item Value="problemDescription"/>
<Item Value="requestDate"/>
<Item Value="status"/>
<Item Value="svrId"/>
</AttrNames>
</table>
...
</bindings>
同じメソッドが使用されているため、表をドロップしたときに、新しいメソッド・バインディングは作成されません。詳細は、7.2.2項「データ・コントロール・パレットを使用した表の作成時に発生する処理」を参照してください。
ユーザーがデータを入力してフォームを送信すると、変数に値が移入され、NamedDataElementの値に対するEL式を使用して、属性バインディングによってメソッドのパラメータの値が提供されるようになります。
|
ヒント: 検索フォームおよび結果表が同じページにある場合、ユーザーがそのページに初めてアクセスしたときに、イテレータからのすべてのレコードが表に表示されます。ユーザーが実際に検索を実行するまで結果表が表示されないようにすることができます。手順は、10.9項「検索ページの結果表の条件付き表示」を参照してください。 |
ユーザーが対応するinputTextコンポーネントにステータスとしてClosedを入力し、コマンド・ボタンをクリックすると、次の処理が実行されます。
findServiceRequestSearch_status変数に値Closedが移入されます。
次のように、この属性バインディングは、変数イテレータを参照するため、statusの値を取得できます。
<attributeValues id="status" IterBinding="variables">
<AttrNames>
<Item Value="findServiceRequestSearch_statusParam"/>
</AttrNames>
</attributeValues>
次のように、NamedData要素には属性バインディングのアイテム値に対して評価するEL式が含まれているため、パラメータは値にもアクセスできます。
<NamedData NDName="status" NDType="java.lang.String"
NDValue="${bindings.findServiceRequests_statusParam}"/>
NamedData要素から値を取得するパラメータを使用して、findServiceRequestSearchメソッドが実行されます。
findServiceRequestSearchメソッドによって、パラメータ値と一致するレコードのコレクションが戻されます。
findServiceRequestSearchIterイテレータによってコレクションが反復処理されるため、表に結果が表示されるようになります。実行時の表の詳細は、7.2.2項「データ・コントロール・パレットを使用した表の作成時に発生する処理」を参照してください。
検索フォームおよび結果表が同じページにある場合、ユーザーがそのページに初めてアクセスしたときに、イテレータからのすべてのレコードが表に表示されます。ユーザーが実際に検索を実行するまで結果表が表示されないようにすることができます。図10-12は、ユーザーが初めてアクセスしたときのSRSearchページの表示を示しています。
ユーザーが検索を実行すると、図10-13のように結果表が表示されます。
条件付きで結果表を表示するには、UIコンポーネント(表自体または表コンポーネントを保持する別のコンポーネント)について、ユーザーによる検索ページへのアクセスが1回目かどうかに対して評価するEL式を入力する必要があります。マネージドBeanのフィールドには、式で使用された値が保持されます。
条件付きで結果表を表示する手順:
同じページで検索フォームおよび結果表を作成します。手順は、10.8項「検索ページの作成」を参照してください。
マネージドBeanで、ユーザーによるページへのアクセスが1回目の場合に設定されるフラグを作成します。たとえば、SRDemoアプリケーションのuserStateマネージドBeanには、SEARCH_FIRSTTIME_FLAGパラメータが含まれます。ページをレンダリングするかどうかを判断するために、ページのEL式は、このパラメータの値を認識する必要があります(手順4を参照)。このBeanがEL式に対してインスタンス化されると、isSearchFirstTimeメソッドによってこのフィールドがチェックされます。フィールドがnullの場合は、値がTrueに設定されます。マネージドBeanの作成方法の詳細は、10.2項「マネージドBeanを使用した情報の格納」を参照してください。
JSFページで、setActionListenerコンポーネントを、この検索の実行に使用されるコマンド・コンポーネントに挿入します。from属性を#{false}に設定します。to属性を、手順2で作成したマネージドBeanのフィールドに設定します。これにより、このボタンがクリックされるたびに、このフィールドがfalseに設定されます。setActionListenerコンポーネントの使用方法の詳細は、10.4項「コマンド・コンポーネントを使用したパラメータ値の設定」を参照してください。
例10-18は、SRSearchページの「検索」ボタンのコードを示しています。
JSFページでRendered属性の値としてEL式を使用し、変数が特定の値の場合のみUIコンポーネント(表または表を保持するUIコンポーネント)によってレンダリングが行われるようにします。
例10-19は、SRSearchページでpanelGroupコンポーネントのRendered属性の値に使用されるEL式を示しています。
このEL式により、searchFirstTimeフラグの値がFalseの場合のみ、panelGroupコンポーネントによってレンダリングが行われます。
マネージドBeanを使用して値を保持すると、その他のオブジェクトによる値の設定および値へのアクセスがともに可能になります。たとえば、パラメータ値の引渡しと同様に、setActionListenerコンポーネントを使用してマネージドBeanに値を設定すると、コンポーネントのrendered属性のEL式がその値にアクセスできるようになります。
たとえば、ユーザーが初めてSRSearchページにアクセスした場合は、次の処理が行われます。
表を保持するpanelGroupコンポーネントには、そのrendered属性のEL式が含まれており、EL式がuserState Beanを参照するため、このBeanがインスタンス化されます。
ユーザーはまだページにアクセスしていないため、userState BeanのSEARCH_FIRSTTIME_FLAGフィールドは未設定であり、値はnullです。
値がnullであるため、このBeanのisSearchFirstTimeメソッドによって、値がtrueに設定されます。
EL式が評価され、SRSearchページが表示されますが、SEARCH_FIRSTTIME_FLAGフィールドがtrueであることから、ネストされた表などのパネル・グループはレンダリングされません。
ユーザーが検索条件を入力して「検索」ボタンをクリックすると、関連付けられているsetActionListenerコンポーネントによって、userState BeanのsearchFirstTime値がfalseに設定されます。
コマンド・ボタンの結果が定義されていないため、ユーザーは同じページにとどまります。
この時点ではsearchFirstTimeの値がfalseに設定されているため、結果を使用してページが再レンダリングされると、panelGroupコンポーネントによって結果を含む表が表示されます。