Oracle® Fusion Middleware Oracle Application Development Framework Fusion開発者ガイド 11g リリース2(11.1.2.3.0) B69399-02 |
|
前 |
次 |
この章では、より複雑なバインディングをページに追加する方法について説明します。フォームおよびコマンド・コンポーネントを作成するためのパラメータを取るメソッドの使用方法についても説明します。
この章の内容は次のとおりです。
注意: この章で説明する実装メソッドのいくつかは、ページレベルの設計のためのものです。タスク・フローを使用している場合は、同じ機能の多くを実行できます。詳細は、第18章「ADFタスク・フローの概説」を参照してください。 |
基本的なページを作成してナビゲーション機能を追加すると、ページ間でパラメータを渡したり、宣言アクションを上書きする機能を提供するなどの、より複雑な機能を追加できます。Oracle ADFには、このような複雑な機能を実際のコードをほとんど使用せずに追加できる機能が数多く用意されています。
この章で説明する機能のいくつかは、他のメソッドでも実行できます。たとえば、個別のページ・フローではなくタスク・フローを使用している場合、タスク・フローのパラメータ渡しメカニズムを使用する必要があります。あるいは、ADF Business Componentsを使用している場合は、ADF Model検証規則ではなく、データ・モデル・プロジェクトにあるエンティティ・オブジェクトの検証規則を使用する必要があります。Business Componentsの検証規則の詳細は、第7章「検証とビジネス・ルールの宣言的な定義」を参照してください。
コマンド・コンポーネントを使用すると、パラメータの引渡し、宣言アクションのオーバーライド、なんらかのロジックの実行といったアクションを実行できます。「データ・コントロール」パネルでコマンド・コンポーネントをカスタム・メソッドにバインドできます。たとえば、updateItemInCart(Integer, Integer, Boolean)
というカスタム・メソッドがある場合、ボタンを作成してこのメソッドにバインドすると、ユーザーがこのボタンを押したときにショッピング・カートを更新できます。
コマンド・コンポーネント内でsetPropertyListener
タグを使用して、イベント発生時に値を割り当てることもできます。たとえば、検索を開始して、マネージドBeanに保存されたパラメータ値に基づき、別のページ上に検索結果を表示するボタンを作成できます。setPropertyListener
プロパティを使用して、値をチェックするメソッドにこのパラメータ値を渡します。
コマンド・コンポーネントにバインドされた宣言メソッドにコードを追加できます。たとえば、宣言的なCommit
ボタンを作成した後、マネージドBeanにコードを追加してから、追加処理用にCommit
操作をオーバーライドできます。
コマンド・コンポーネントの処理を開始する前に、その他のADF機能を理解しておくと役に立ちます。次に、関連する他の機能へのリンクを示します。
コマンド・コンポーネントとしてページに追加可能なカスタム・メソッドの作成の詳細は、9.7項「サービス・メソッドによるアプリケーション・モジュールのカスタマイズ」および9.9項「UIクライアントへのカスタム・サービス・メソッドの公開」を参照してください。
操作によるコマンド・コンポーネントの作成の詳細は、26.4.2項「コマンド・ボタンの作成時の処理」を参照してください。
メソッド内でEL式を使用する場合は、26.4.2.3項「EL式を使用したナビゲーション操作へのバインド」を参照してください。
コマンド・ボタンのactionListener
属性の詳細は、26.4.3項「実行時に行われる処理: アクション・イベントおよびアクション・リスナーの動作方法」を参照してください。
ADFバインディングの詳細は、13項「Fusion WebアプリケーションでのADF Modelの使用」を参照してください。
タスク・フローを使用している場合、タスク・フローのパラメータ渡しメカニズムを使用できます。詳細は、第20章「タスク・フローのパラメータの使用」を参照してください。
タスク・フローのコール・メソッドの使用を検討している場合は、19.5項「メソッド・コール・アクティビティの使用」を参照してください。
マネージドBeanを使用する場合は、24.4項「Fusion WebアプリケーションでのマネージドBeanの使用」を参照してください。
アプリケーションにカスタム・メソッドが含まれている場合、これらのメソッドは「データ・コントロール」パネルに表示されます。これらのメソッドは、コマンド・ボタンとしてドラッグ・アンド・ドロップできます。ユーザーがボタンをクリックすると、メソッドが実行されます。
カスタム・メソッドの作成の詳細は、9.7項「サービス・メソッドによるアプリケーション・モジュールのカスタマイズ」および9.9項「UIクライアントへのカスタム・サービス・メソッドの公開」を参照してください。
たとえば、Fusion Order DemoアプリケーションのStoreFrontモジュールのアプリケーション・モジュールにはupdateItemInCart(Integer, Integer, Boolean)
メソッドが含まれています。このメソッドは、ショッピング・カート内の項目を更新します。ユーザーがこのメソッドを実行できるようにするには、図26-1のように、「データ・コントロール」パネルからupdateItemInCart(Integer, Integer Boolean)
メソッドをドラッグします。
要求されるビジネス・ロジックを実行するために、多くのメソッドでは、そのパラメータ(1つ以上)に対する値を必要とします。つまり、メソッドにバインドされたボタンを作成する際に、パラメータの値の取得元を指定する必要があります。たとえば、updateItemInCart(Integer, Integer, Boolean)
メソッドを使用する場合、更新するアイテムを指定する必要があります。
作業を始める前に、次のようにします。
カスタム・メソッドについて理解しておくと役立ちます。詳細は、28.2項「メソッドを実行するためのコマンド・コンポーネントの作成」を参照してください。
また、他のコマンド・コンポーネントを使用して追加できる機能について理解しておくと役立ちます。詳細は、28.1.2項「コマンド・コンポーネントの追加機能」を参照してください。
カスタム・メソッドにバインドされたコマンド・コンポーネントを作成するには:
「データ・コントロール」パネルから、メソッドをページにドラッグします。
ヒント: 表またはフォームに含まれるデータを使用するメソッドのボタンをドロップする場合は、その表またはフォームの中にボタンをドロップする必要があります。 |
ポップアップ・メニューから「作成」>→「メソッド」>→「ADFボタン」を選択します。
メソッドがパラメータを取る場合は、「アクション・バインディングの編集」ダイアログが開きます。「アクション・バインディングの編集」ダイアログで、各パラメータの値を入力するか、「パラメータ」の「値」列で「EL式ビルダーの表示」メニュー選択をクリックし、EL式ビルダーを起動します。
メソッドをコマンド・ボタンとしてドロップすると、JDeveloperによって次の処理が行われます。
メソッドのメソッド・アクション・バインディングが定義されます。
メソッドがパラメータを取得する場合は、パラメータ値を保持するNamedData
要素が作成されます。
ADF Facesコマンド・コンポーネント用のコードがJSFページに挿入されます。
actionListener
を使用して、ボタンにメソッドをバインドします。
メソッド・コールからの戻り値を使用します。
JDeveloperはメソッドにアクション・バインディングを追加します。アクション・バインディングはRequiresUpdateModel
プロパティを使用して、アクションを実行する前にモデルを更新する必要があるかどうかを判別します。コマンド操作の場合、デフォルトではこのプロパティはtrue
に設定されています。つまり、ビュー・レイヤーでのすべての変更は、操作を実行する前にモデルに移動する必要があります。
パラメータを取得するメソッドをJSFページにドロップすると、メソッド・アクション・バインディングが作成されます。このバインディングにより、ユーザーがコマンド・コンポーネントをクリックしたときにメソッドが実行されるようになります。メソッドが実行するパラメータを要求する場合は、JDeveloperによって、各パラメータのNamedData
要素も作成されます。これらの要素は、メソッドのパラメータを表します。
たとえば、updateItemInCart(Integer, Integer, Boolean)
メソッド・アクション・バインディングには、パラメータに対するNamedData
要素が含まれます。この要素は、アクション・バインディングの作成時に指定した値にバインドされます。例28-1に、updateItemInCart(Integer, Integer, Boolean)
メソッドをドロップし、Integer
パラメータ(productId
)と別のInteger
パラメータ(quantity
)およびBoolean
パラメータ(named isSet
)を適切な変数にバインドしたときに作成されるメソッド・アクション・バインディングを示します。
例28-1 パラメータ・メソッドのメソッド・アクション・バインディング
<methodAction id="updateItemInCart" InstanceName="StoreServiceAMDataControl.dataProvider" DataControl="StoreServiceAMDataControl" RequiresUpdateModel="true" Action="invokeMethod" MethodName="updateItemInCart" IsViewObjectMethod="false"> <NamedData NDName="productId" NDType="java.lang.Integer"/> <NamedData NDName="quantity" NDType="java.lang.Integer"/> <NamedData NDName="isSet" NDType="java.lang.Boolean"/> </methodAction>
JDeveloperはADF Facesコンポーネント用のコードをJSFページに追加します。26.4.2.3項「EL式を使用したナビゲーション操作へのバインド」で説明されているとおり、このコードは、他のどのコマンド・ボタンのコードとも同じです。ただし、このボタンは、組込み操作に対するアクション・バインディングのexecute
メソッドではなく、ドロップされたメソッドに対するメソッド・アクション・バインディングのexecute
メソッドにバインドされます。
操作を使用してコマンド・ボタンを作成するときと同様に、メソッドを使用してコマンド・ボタンを作成すると、actionListener
属性を使用して、ボタンがメソッドに自動的にバインドされます。ボタンは、EL式を使用して、指定されたメソッドのアクション・バインディングのexecute
プロパティにバインドされます。このEL式により、アプリケーション・モジュールに対してバインディングのメソッドが起動します。コマンド・ボタンのactionListener
属性の詳細は、26.4.3項「実行時に行われる処理: アクション・イベントおよびアクション・リスナーの動作方法」を参照してください。
ヒント: アクション・バインディングの |
ナビゲーション操作のように、ボタンのdisabled
プロパティは、EL式を使用してボタンを表示するかどうかを決定します。例28-2に、コマンド・ボタンをupdateItemInCart(Integer, Integer, Boolean)
メソッドにバインドするためのEL式を示します。
例28-2 コマンド・ボタンをメソッドにバインドするためのJSFコード
<af:commandButton actionListener="#{bindings.updateItemInCart.execute}" text="updateItemInCart" disabled="#{!bindings.updateItemInCart.enabled}"/>
ヒント: コマンド・ボタン・コンポーネントをページにドロップすると、以前にドロップされた同種のコンポーネントの数に基づいて自動的にIDが付けられます。たとえば、 |
メソッド・コールからの戻り値を使用することもできます。例28-3に、文字列値を戻すカスタム・メソッドを示します。
例28-3 値を戻すカスタム・メソッド
/** * Custom method. */ public String getHelloString() { return ("Hello World"); }
例28-4に、コマンド・ボタンおよびoutputText
コンポーネントのJSFページのコードを示します。
例28-4 カスタム・メソッドをコールするコマンド・ボタン
<af:commandButton actionListener="#{bindings.getHelloString.execute}" text="getHelloString" disabled="#{!bindings.getHelloString.enabled}" id="helloButtonId"/> <af:outputText value="#{bindings.return.inputValue}" id="helloOutputId"/>
ユーザーがコマンド・ボタンをクリックすると、カスタム・メソッドがコールされます。このメソッドは、outputText
コンポーネントの値として表示される文字列「Hello World」を戻します。
1つのページでのアクションに対して、アプリケーション機能を判別するためのパラメータを設定する必要が生じる場合があります。たとえば、あるページから別のページの結果表へ移動する検索コマンド・ボタンを作成できます。ただし、結果表が表示されるのはパラメータ値がfalse
の場合のみです。
ページ間でこのパラメータを渡す場合やパラメータ値のチェックに使用するメソッドを含める場合には、マネージドBeanを使用できます。検索ページのレンダリング時にマネージドBeanがインスタンス化され、このBeanのメソッドによってこのパラメータがチェックされます。このパラメータがnull
の場合(ページが初めてレンダリングされる場合)は、値がtrue
に設定されます。
カスタム・メソッドの作成の詳細は、9.7項「サービス・メソッドによるアプリケーション・モジュールのカスタマイズ」および9.9項「UIクライアントへのカスタム・サービス・メソッドの公開」を参照してください。
type
プロパティがaction
に設定されたsetPropertyListener
コンポーネント(この検索を実行したコマンド・ボタンにネストされている)を使用してこのフラグがfalse
に設定されるため、検索の実行後に結果表が表示されるようになります。マネージドBeanの使用の詳細は、24.4項「Fusion WebアプリケーションでのマネージドBeanの使用」を参照してください。
setPropertyListener
コンポーネントを使用して、その他のオブジェクトの値を設定できます。このコンポーネントは、コマンド・コンポーネントの子である必要があります。
作業を始める前に、次のようにします。
setPropertyListener
およびマネージドBeanを使用して値を設定する方法について理解しておくと役立ちます。詳細は、28.3項「コマンド・コンポーネントを使用したパラメータ値の設定」を参照してください。
また、他のコマンド・コンポーネントを使用して追加できる機能について理解しておくと役立ちます。詳細は、28.1.2項「コマンド・コンポーネントの追加機能」を参照してください。
次のタスクを完了する必要があります。
setPropertyListenerコンポーネントを使用するには:
コンポーネント・パレットの「操作」パネルからsetPropertyListenerコンポーネントをドラッグして、子としてコマンド・コンポーネントにドロップします。
または、このコンポーネントを右クリックし、「内側ボタンの挿入」→「ADF Faces」→setPropertyListenerを選択します。
「プロパティ・リスナーの設定の挿入」ダイアログの「選択元」フィールドにパラメータ値を入力します。
「先」フィールドにパラメータのターゲットを入力します。
ヒント: 作成されるページのページ定義ファイルに直接パラメータ値を設定するかわりに、マネージドBeanまたはスコープにパラメータ値を格納することを考慮してください。次のページに直接設定すると、それ以降、ナビゲーションを簡単に変更できなくなります。詳細は、24.4項「Fusion WebアプリケーションでのマネージドBeanの使用」を参照してください。また、バインディング・コンテナ内のデータは、コンテナが準備されたリクエスト中にのみ有効です。データを設定してから次のページがレンダリングされるまでの間に、データが変更される場合があります。 |
「タイプ」ドロップダウン・メニューから「アクション」を選択します。
「OK」をクリックします。
setPropertyListener
コンポーネントを使用すると、次のページに移動する前にコマンド・コンポーネントによって値が設定されます。渡す必要がある値のソースまたは実際の値をfrom
属性に設定すると、コンポーネントからその値へのアクセスが可能になります。to
属性をターゲットに設定すると、コマンド・コンポーネントによってターゲットに値が設定されるようになります。例28-5に、false
値を取得し、その値をsearchResults
マネージドBeanのinitialSearch
フラグの値として設定するコマンド・コンポーネントのJSFページのコードを示します。
ユーザーがコマンド・コンポーネントをクリックすると、移動する前に、setPropertyListener
コンポーネントによってパラメータ値が設定されます。例28-4では、setPropertyListener
はfalse
値を取得し、その値をsearchResults
マネージドBeanのinitialSearch
属性の値として設定しています。これで、レンダリングするかどうかを決定するためにこの値を認識する必要があるコンポーネントは、EL式#{searchResults.initialSearch}
を使用してアクセスできます。
操作またはメソッドをコマンド・ボタンとしてドロップすると、操作またはメソッドのexecute
メソッドに、そのボタンが自動的にバインドされます。ただし、既存のロジックの前または後に、ロジックの追加が必要になる場合もあります。
JDeveloperを使用すると、バインディング・コンテナにアクセスするマネージドBeanにメソッドおよびプロパティを新規作成することにより、宣言的操作にロジックを追加できます。デフォルトでは、この生成されたコードによって、操作またはメソッドが実行されます。その後、このコードの前か後にロジックを追加できます。元の操作またはメソッドのexecute
プロパティではなく、この新規メソッドにコマンド・コンポーネントが自動的にバインドされます。その後、ユーザーがボタンをクリックすると、新規メソッドが実行されます。
たとえば、Fusion Order Demoアプリケーションの注文ページのCommit
操作には、追加処理が必要です。「コミット」ボタンは「発注」に名前が変更され、orderPageBean
マネージドBeanのsubmitOrders
メソッドにロジックが追加されます。
宣言メソッドを上書きするには、マネージドBeanにコマンド・コンポーネントがバインドされる新規メソッドを保持させる必要があります。ページにバッキングBeanが関連付けられている場合は、JDeveloperによって、バインディング・オブジェクトへのアクセスに必要なコードがバッキングBeanに追加されます。ページにバッキングBeanが関連付けられていない場合は、作成を促す指示が表示されます。
コマンド・コンポーネントを追加して、マネージドBeanを使用してその宣言メソッドをオーバーライドできます。
作業を始める前に、次のようにします。
宣言メソッドのオーバーライド方法について理解しておくと役立ちます。詳細は、28.4項「宣言メソッドのオーバーライド」を参照してください。
また、他のコマンド・コンポーネントを使用して追加できる機能について理解しておくと役立ちます。詳細は、28.1.2項「コマンド・コンポーネントの追加機能」を参照してください。
次のタスクを完了する必要があります。
注意: 現在、コマンド・コンポーネントの |
宣言メソッドの上書きの手順:
上書きする操作またはメソッドをJSFページ上にドラッグし、UIコマンド・コンポーネントとしてドロップします。
コンポーネントが作成され、ActionListener
属性を使用してADF Modelレイヤーの関連するバインディング・オブジェクトにバインドされます。
「データ・コントロール」パネルでメソッドを使用したコマンド・コンポーネントの作成の詳細は、28.2項「メソッドを実行するためのコマンド・コンポーネントの作成」を参照してください。
操作によるコマンド・コンポーネントの作成の詳細は、26.4.2項「コマンド・ボタンの作成時の処理」を参照してください。
JSFページでコンポーネントをダブルクリックします。
「バインドActionプロパティ」ダイアログで、次のいずれかの方法で、バッキングBeanとコンポーネントのバインド先とするメソッドを指定します。
自動バインディングがそのページで有効化されている場合は、図28-2のように、バッキングBeanはすでに自動選択されています。
新規メソッドを作成するには、「メソッド」フィールドにメソッドの名前を入力します。このフィールドには、最初にデフォルト名が表示されています。
または
既存のメソッドを使用するには、「メソッド」フィールドのドロップダウン・リストからメソッドを選択します。
「生成にADFバインディングを使用」を選択します。
そのページで自動バインディングが使用されていない場合は、図28-3のように、既存のバッキングBeanから選択するか、新規作成できます。
「新規」をクリックして、新しいバッキングBeanを作成します。「マネージドBeanの作成」ダイアログで、Beanおよびクラスに名前を付け、Beanのスコープを設定します。
または
既存のバッキングBeanおよびメソッドをドロップダウン・リストから選択します。
注意: コマンド・コンポーネントに |
バッキングBeanおよびメソッドを識別したら、「バインドActionプロパティ」ダイアログで「OK」をクリックします。
ソース・エディタでマネージドBeanが自動的に開きます。例28-6は、Beanに挿入されたコードを示しています。この例では、コマンド・ボタンがCommit
操作にバインドされています。
例28-6 バインディング・オブジェクトへのアクセス用にバッキングBeanで生成されたコード
public String submitOrder() { BindingContainer bindings = getBindings(); OperationBinding operationBinding = bindings.getOperationBinding("Commit"); Object result = operationBinding.execute(); if (!operationBinding.getErrors().isEmpty()) { return null; } }
これで、例28-7に示すように、バインディング・オブジェクトにアクセスする前または後に、ロジックを追加できます。
例28-7 上書き後のメソッドに追加されたコード
public String submitOrder() { DCBindingContainer bindings = (DCBindingContainer)JSFUtils.resolveExpression("#{bindings}"); OperationBinding operationBinding = bindings.getOperationBinding("Commit"); JUCtrlAttrsBinding statusCode = (JUCtrlAttrsBinding)bindings.findNamedObject("OrderStatusCode"); statusCode.setAttribute("OrderStatusCode", "PENDING"); JUCtrlAttrsBinding orderDate = (JUCtrlAttrsBinding)bindings.findNamedObject("OrderDate"); orderDate.setAttribute("OrderDate", new Date()); JUCtrlAttrsBinding orderId = (JUCtrlAttrsBinding)bindings.findNamedObject("OrderId"); JSFUtils.storeOnSession("orderId", orderId.getAttribute("OrderId")); JUCtrlAttrsBinding invoiceTotal = (JUCtrlAttrsBinding)bindings.findNamedObject("InvoiceTotal"); JUCtrlAttrsBinding orderTotal = (JUCtrlAttrsBinding)bindings.findNamedObject("OrderTotal"); orderTotal.setAttribute("OrderTotal", invoiceTotal.getAttribute("InvoiceTotal")); Object result = operationBinding.execute(); ShoppingCartBean shoppingCartBean = (ShoppingCartBean)JSFUtils.resolveExpression("#{shoppingCartBean}"); shoppingCartBean.removeAllItems(); return "orderSummary"; }
例28-7のコードは、FODユーティリティ・メソッドJSFUtils.resolveExpression
を使用して、EL式を解決しています。このようなメソッドのコードは、例28-8にあるコードに似ています。
例28-8 EL式を解決するためのユーティリティ・メソッド
public static Object resolveExpression(String expression) { FacesContext facesContext = getFacesContext(); Application app = facesContext.getApplication(); ExpressionFactory elFactory = app.getExpressionFactory(); ELContext elContext = facesContext.getELContext(); ValueExpression valueExp = elFactory.createValueExpression(elContext, expression, Object.class); return valueExp.getValue(elContext); }
処理ロジックに加えて条件付きロジックを記述し、複数の結果の中から1つを戻すこともできます。たとえば、処理中にエラーが発生した場合にはnull
を、処理が正常終了した場合は別の結果値を戻すことができます。null
の戻り値により、ナビゲーション・ハンドラはナビゲーション・ケースを評価せずに、そのまま現在ページを再表示します。
ヒント: 特定のナビゲーション・ケースをトリガーするには、メソッドによって戻される結果値が、ナビゲーション・ルールの結果値と(大/小文字も含めて)完全に一致する必要があります。 |
この時点で、コマンド・ボタンは、ActionListener
属性ではなく、Action
属性を使用して新しいメソッドにバインドされています。Action
属性の値(結果文字列など)がすでに存在していた場合は、その値が新規メソッドの戻りとして追加されます。値が存在していなかった場合は、戻りがnull
のままになります。
宣言メソッドをオーバーライドすると、JDeveloperにより、管理プロパティがバッキングBeanに追加され、この管理プロパティに値#{bindings}
(バインディング・コンテナへの参照)が設定されます。また、強く型付けされたBeanプロパティがBindingContainer
型のクラスに追加され、JSFランタイムにより、値として管理プロパティ式#{bindings}
が設定されます。また、JDeveloperはUIコマンド・アクション・メソッドにロジックを追加します。このロジックには、現在のバインディング・コンテナへのアクセスに使用されている、強く型付けされたgetBindings()
メソッドが含まれます。
このコードによって行われる処理は次のとおりです。
バインディング・コンテナにアクセスします。
関連付けられているメソッドのバインディングを検索し、実行します。
ナビゲーションに使用できるメソッドの戻り値を追加します。デフォルトでは、戻り値はnull
です。ボタンのAction
属性に結果文字列がすでに存在する場合は、その属性が戻り値として使用されます。このコードは、必要に応じて変更できます。
ActionListener
属性ではなく、Action
属性を使用して新しいメソッドにUIコマンド・コンポーネントがリバインドされます。例28-9に、Commit
操作が宣言的にページに追加される場合のコードを示します。
例28-9 宣言メソッドにバインドされたコマンド・ボタンのJSFページ・コード
<af:commandButton actionListener="#{bindings.Commit.execute}" text="Commit" disabled="#{!bindings.Commit.enabled}"/>
例28-10に、ページのバッキングBeanのメソッドを上書きした後のコードを示します。ここでは、action
属性は、バッキングBeanのメソッドにバインドされています。
例28-10 上書き後のメソッドにバインドされたコマンド・ボタンのJSFページ・コード
<af:commandButton text="#{res['order.cart.submit']}" action="#{orderPageBean.submitOrder}"/>
ヒント: 上書き後のメソッドを使用するボタンをクリックすると、次のエラーが表示されます。
これは、上書き後のメソッドを含むマネージドBeanのスコープが、 |