ヘッダーをスキップ
Oracle® Fusion Middleware Oracle Application Development Framework Java EE開発者ガイド
11g Release 1 (11.1.1.7.0)
B61007-05
  目次へ移動
目次
索引へ移動
索引

前
 
次
 

3 データバインドされた基本的なページの作成

この章では、「データ・コントロール」パネルを使用して、ADF Facesコンポーネントに基づいてデータバインドされた基本的なページを作成する方法について説明します。テキスト・フィールドを個々の属性から作成する方法、アクセッサによって返されるコレクションからフォーム全体を生成する方法、および既存レコードを編集したり新規レコードを作成するためのフォームを作成する方法についても説明します。

この章の内容は次のとおりです。

3.1 データバインドされた基本的なページの作成の概要

ビジネス・サービス用に作成されたデータ・コントロールを使用して情報の表示および収集を実行するための、UIページを作成できます。たとえば、「データ・コントロール」パネルを使用して、項目の属性をドラッグし、読取り専用テキストまたはラベル付き入力テキスト・フィールドとして、値を表示できます。関連データの表示および更新に必要なすべてのJSFタグとバインディング・コードがJDeveloperによって作成されます。「データ・コントロール」パネルおよび宣言的なバインディング機能の詳細は、第2章「Java EE WebアプリケーションでのADFモデル・データ・バインディングの使用」を参照してください。

JDeveloperでは、属性を個別にドロップするのではなく、オブジェクトのすべての属性をフォームとして一度にドロップできます。フォームを構成する実際のUIコンポーネントは、ドロップしたフォームのタイプによって異なります。値を表示するフォーム、ユーザーが値を編集できるフォームおよび値を収集するフォーム(入力フォーム)を作成できます。

たとえば、Suppliersモジュールには、ユーザーが仕入先に関する情報を表示したり編集できる、図3-1に示すようなページが含まれています。このフォームは、「データ・コントロール」パネルからsupplierFindAllアクセッサ・コレクションをドラッグ・アンド・ドロップして作成されました。

図3-1 Suppliersモジュールの仕入先詳細フォーム

サプライヤ詳細編集フォーム

UIコンポーネントを作成すると、コレクション内のレコード間を移動できるようにしたり、ユーザーがデータを操作できるようにする組込み操作をコマンドUIコンポーネントとしてドロップできます。たとえば、フォームに表示されたデータ・オブジェクトをユーザーが削除できるようにするためのボタンを作成できます。また、必要に応じてデフォルトのコンポーネントを変更することもできます。

3.2 属性を使用したテキスト・フィールドの作成方法

JDeveloperでは、テキスト・フィールドを宣言的に作成可能な、JSFページ用の完全なWYSIWYG開発環境が用意されているため、ページのほとんどの内容をコードを見ずに設計できます。「データ・コントロール」パネルから項目をドラッグ・アンド・ドロップすると、属性バインディングを使用してADF FacesテキストUIコンポーネントがデータ・コントロールの属性に宣言的にバインドされます。

3.2.1 テキスト・フィールドの作成方法

属性を表示または更新できるテキスト・フィールドを作成するには、「データ・コントロール」パネルからコレクションの属性をドラッグ・アンド・ドロップします。

バインドされたテキスト・フィールドの作成手順:

  1. 「データ・コントロール」パネルから、コレクションの属性を選択します。属性およびその他のオブジェクトを表す「データ・コントロール」パネルのアイコンの説明は、表2-1を参照してください。

    たとえば、図3-2は、SupplierモジュールのSupplierFacedLocalデータ・コントロールのaddressFindAllアクセッサ・コレクション下のaddress1属性を示しています。この属性は、住所の最初の部分を表示または入力する場合にドロップします。

    図3-2 コレクションに関連付けられた属性の「データ・コントロール」パネルでの表示

    CustomerRegistrationの属性
  2. ページに属性をドラッグし、ポップアップ・メニューから、属性値を表示または収集するウィジェットのタイプを選択します。各属性について、次の選択肢があります。

    • テキスト:

      • ラベル付ADF入力テキスト: ネストされたvalidatorコンポーネントを伴うADF Faces inputTextコンポーネントが作成されます。label属性が移入されます。


        ヒント:

        inputTextコンポーネントのバリデータおよびその他の属性の詳細は、『Oracle Fusion Middleware Oracle Application Development Framework Webユーザー・インタフェース開発者ガイド』の「入力コンポーネントの使用とフォームの定義」を参照してください。


      • ADF入力テキスト: ネストされたvalidatorコンポーネントを伴うADF Faces inputTextコンポーネントが作成されます。label属性は移入されません。

      • ラベル付ADF出力テキスト: ADF Faces outputTextコンポーネントを保持するpanelLabelAndMessageコンポーネントを作成します。panelLabelAndMessageコンポーネントのlabel属性が移入されます。

      • ADF出力テキスト: ADF Faces outputTextコンポーネントを作成します。ラベルは作成されません。

      • ラベル付ADF出力フォーマット済: 「ラベル付ADF出力テキスト」と同様ですが、outputTextコンポーネントのかわりにoutputFormattedコンポーネントを使用します。outputFormattedコンポーネントでは、制限された分量のHTML書式設定を追加できます。詳細は、『Oracle Fusion Middleware Oracle Application Development Framework Webユーザー・インタフェース開発者ガイド』の出力テキストの表示に関する項とフォーマット済の出力テキストに関する項を参照してください。

      • ADF出力フォーマット済: 「ラベル付ADF出力フォーマット済」と同様ですが、ラベルはありません。

      • ADFラベル: ADF Faces outputLabelコンポーネント。

    • 単一選択: 単一選択リストを作成します。JSFページでのリストの作成の詳細は、第6章「データバインドされた選択リストの作成」を参照してください。

    この章の目的に合せて、ここではテキスト・コンポーネントのみ(リストは除く)について説明します。

3.2.2 テキスト・フィールドの作成時の処理

JSFページに属性をドラッグしてUIコンポーネントとしてドロップすると、そのページのページ定義ファイル(すでに存在する場合を除く)などが作成されます。属性をページにドラッグした場合の詳細な説明は、第2.4.2項「「データ・コントロール」パネルを使用したUIコンポーネントの作成時の処理」を参照してください。イテレータと属性のバインディングが作成されてページ定義ファイルに追加されます。また、UIコンポーネントに必要なJSPXページ・コードがJSFページに追加されます。

3.2.2.1 イテレータ・バインディングの作成および使用

「データ・コントロール」パネルからコレクションの一部である項目をドロップして(またはコレクション全体をフォームまたは表としてドロップして)ページ上にUIコンポーネントを作成するたびに、イテレータ・バインディングが自動的に作成されます(すでに存在する場合を除く)。イテレータ・バインディングは、データ・コレクションのイテレータを参照し、この機能によりそのデータ・オブジェクトを反復処理します。また、コレクション内のデータ・オブジェクトの現在行および状態を管理します。イテレータ・バインディングは実際にはデータにアクセスしません。かわりに、データにアクセスできるオブジェクトを単純に公開し、コレクション内の現在のデータ・オブジェクトを指定します。その後、現在のオブジェクトのデータを戻したり、オブジェクトのデータに対してアクションを実行するために、他のバインディングがこのイテレータ・バインディングを参照します。イテレータ・バインディングはイテレータではないことに注意してください。これはイテレータへのバインディングです。

たとえば、addressFindAllコレクション下にaddress1属性をドロップすると、JDeveloperによって、
SupplierFacadeLocal
データ・コントロールに対するイテレータ・バインディングとaddressFindAllアクセッサに対するaccessorIteratorバインディングが作成され、SupplierFacadeLocalイテレータがマスター・バインディングになります。


ヒント:

アクセッサから返されるコレクションごとにアクセッサ・イテレータ・バインディングが1つ作成されます。つまり、同じアクセッサから2つの属性をドロップした場合(もしくは同じ属性を2回ドロップした場合)は、同じバインディングが使用されます。コンポーネントごとに動作の異なるバインディングが必要な場合を除き、これで問題はありません。その場合は、別個のイテレータ・バインディングを手動で作成する必要があります。


イテレータ・バインディングのrangeSize属性は、イテレータ・バインディングへのアクセスが行われるたびにデータ・コントロールからフェッチされるデータ行数を決定します。この属性により、行セット全体の中のある絶対開始位置にある1-n行の相対セットが得られます。デフォルトでは、属性は25に設定されています。例3-1に、addressFindAllアクセッサ・コレクションから属性をドロップすると作成されるイテレータ・バインディングを示します。

例3-1 イテレータ・アクセッサ・バインディングのページ定義コード

<executables>
  <iterator Binds="root" RangeSize="25" DataControl="SupplierFacadeLocal"
            id="SupplierFacadeLocalIterator"/>
  <accessorIterator MasterBinding="SupplierFacadeLocalIterator"
                    Binds="addressesFindAll" RangeSize="25"
                    DataControl="SupplierFacadeLocal"
                    BeanClass="oracle.fodemo.supplier.model.Addresses"
                    id="addressesFindAllIterator"/>
</executables>

このメタデータにより、ADFバインディング・コンテナは属性値にアクセスできます。イテレータ・バインディングは実行可能ファイルで、デフォルトではページのロード時に起動されるため、これによってイテレータがaddressFindAllアクセッサによって返されるコレクションアクセスし、反復処理を実行できます。つまり、イテレータによって、コレクション内のすべてのオブジェクトの管理(コレクション内の現在の行の決定や住所オブジェクトのレンジの決定など)が行われるということです。

3.2.2.2 値バインディングの作成および使用

「データ・コントロール」パネルから属性をドロップすると、UIコンポーネントを属性の値にバインドするための属性バインディングがJDeveloperで作成されます。このタイプのバインディングは、コレクション内の現在行の単一オブジェクトに対する属性の値を表します。値バインディングは、属性値の表示と収集の両方に使用できます。

たとえば、addressFindAllアクセッサの下にあるaddress1属性を「ラベル付ADF出力テキスト」ウィジェットとしてページにドロップすると、JDeveloperによって、address1属性の属性バインディングが作成されます。これにより、バインディングが現在のレコードの属性値にアクセスできるようになります。例3-2は、addressFindAllアクセッサから属性をドロップした場合に作成されるaddress1の属性バインディングを示しています。この属性値は、addressesFindAllIteratorという名前のイテレータを参照します。

例3-2 属性バインディングのページ定義コード

<bindings>
  <attributeValues IterBinding="addressesFindAllIterator" id="address1">
    <AttrNames>
      <Item Value="address1"/> 
    </AttrNames>
  </attributeValues
</bindings>

属性バインディング要素のプロパティの詳細は、『Oracle Fusion Middleware Oracle Application Development Framework Fusion開発者ガイド』のOracleバインディング・プロパティに関する付録を参照してください。

3.2.2.3 EL式を使用したUIコンポーネントのバインド

「データ・コントロール」パネルから属性をドロップしてテキスト・フィールドを作成すると、対応するタグがJSFページに記述され、ドロップしたウィジェットに関連付けられているUIコンポーネントが作成されます。

たとえば、address1属性を「ラベル付出力テキスト」ウィジェットとしてドロップすると、JDeveloperによってpanelLabelAndMessageコンポーネントとoutputTextコンポーネントのタグが挿入されます。また、panelLabelAndMessageコンポーネントのlabel属性を、address1のバインディングのために作成されたヒントのlabelプロパティにバインドするEL式が作成されます。この式は、Javaオブジェクトの構造XMLファイルで設定されているラベルのUIヒントとして評価されます。また、現在の行のaddress1属性の値に評価される、outputTextコンポーネントのvalue属性をaddress1バインディングのinputValueプロパティにバインドする、別の式が作成されます。両方のコンポーネントに対してIDも自動的に生成されます。


ヒント:

JDeveloperでは、すべてのADF FacesコンポーネントのIDが自動的に生成されます。これらの値を必要に応じてオーバーライドできます。


例3-3に、address1属性を「ラベル付出力テキスト」ウィジェットとしてドロップしたときにJSFページで生成されるコードを示します。

例3-3 「ラベル付出力テキスト」としてドロップされた属性のJSFページ・コード

<af:panelLabelAndMessage label="#{bindings.address1.hints.label}"
                         id="plam1">
  <af:outputText value="#{bindings.address1.inputValue}" id="ot1"/>
</af:panelLabelAndMessage>

かわりにaddress1属性を「ラベル付入力テキスト」ウィジェットとしてドロップすると、JDeveloperによってinputTextコンポーネントが作成されます。例3-4に示すように、出力テキスト・コンポーネントと同様、値はaddress1バインディングのinputValueプロパティにバインドされます。さらに、次のプロパティも設定されます。

  • label: オプジェクトに設定されたコントロール・ヒントのlabelプロパティにバインドされます。

  • required: mandatoryプロパティにバインドされ、UIコントロール・ヒントのisNotNullプロパティが参照されます。

  • columns: コントロール・ヒントのdisplayWidthプロパティにバインドされます。このコントロール・ヒント・プロパティは、テキスト・ボックスの幅を決定します。

  • maximumLength: コントロール・ヒントのprecisionプロパティにバインドされます。このコントロール・ヒント・プロパティは、フィールドに入力できる1行当たりの最大文字数を決定します。

さらに、JDeveloperはバリデータ・コンポーネントを追加します。

例3-4 「ラベル付入力テキスト」としてドロップされた属性のJSFページ・コード

<af:inputText value="#{bindings.address1.inputValue}"
              label="#{bindings.address1.hints.label}"
              required="#{bindings.address1.hints.mandatory}"
              columns="#{bindings.address1.hints.displayWidth}"
              maximumLength="#{bindings.address1.hints.precision}">
              shortDesc="#{bindings.address1.hints.tooltip}" id="it1">
  <f:validator binding="#{bindings.address1.validator}"/>
</af:inputText>

これらの値は必要に応じて変更できます。たとえば、構造ファイルでisNotNullコントロール・ヒントはデフォルトではfalseに設定されています。つまり、コンポーネントのrequired属性もfalseと評価されるということです。コンポーネントのrequired属性をtrueに設定すると、この値を上書きできます。属性のすべてのインスタンスを必須にする場合、構造ファイル内のコントロール・ヒントを変更します。すると、すべてのインスタンスが必須となります。これらのプロパティの詳細は、第2.4.2項「「データ・コントロール」パネルを使用したUIコンポーネントの作成時の処理」を参照してください。

3.3 基本的なフォームの作成

コレクションの各属性を個別にドロップしてフォームを作成するかわりに、オブジェクトのすべての属性のデータを表示または収集する、完全なフォームを作成できます。たとえば、「Edit Suppliers Details」ページのフォームは、「データ・コントロール」パネルからproductFindAllアクセッサ・コレクションをドロップして作成されています。

また、コレクションからデータを表示するだけでなく、多くの機能を提供するフォームの作成もできます。ユーザーがデータを更新できるフォームの作成に関する詳細は、3.6項「既存レコードを編集するフォームの作成」を参照してください。ユーザーがコレクションの新規オブジェクトを作成できるフォームの作成に関する詳細は、3.7項「入力フォームの作成」を参照してください。検索フォームを作成することもできます。詳細は、第7章「データバインドされた検索フォームの作成」を参照してください。

3.3.1 フォームの作成方法

データ・コントロールを使用してフォームを作成するには、UIコンポーネントをデータ・コントロールの対応するオブジェクトの属性にバインドします。JDeveloperでは、返されるコレクションを「データ・コントロール」パネルからドラッグ・アンド・ドロップして、宣言的にこの処理を実行できます。

基本的なフォームの作成手順:

  1. 「データ・コントロール」パネルから、表示するデータを返すコレクションを選択します。図3-3は、アクセッサによって返されるコレクションproductFindAllを示しています。

    図3-3 「データ・コントロール」パネルでのproductFindAllアクセッサ

    CustomerInfoコレクション
  2. ページにコレクションをドラッグし、ポップアップ・メニューから、オブジェクトのデータの表示または収集に使用するフォームのタイプを選択します。各フォームについて、次の選択肢があります。

    • ADFフォーム: 「フォーム・フィールドの編集」ダイアログが起動し、デフォルトですべての属性に対して1つのフィールドが作成されるのではなく、属性を個別に選択できます。また、各属性に使用するラベルおよびUIコンポーネントを選択できます。デフォルトでは、ADF inputTextコンポーネントはほとんどの属性で使用されます。inputTextコンポーネントごとにlabel属性が移入されます。

      日付である属性ではInputDateコンポーネントが使用されます。さらに、属性にコントロール・ヒントが作成されている場合、または属性がリストとして構成されている場合、ヒントにより設定されたコンポーネントが使用されます。InputTextコンポーネントには、属性の検証を設定するためのバリデータ・タグが含まれます。属性が数値または日付の場合、コンバータも含まれます。


      ヒント:

      inputTextコンポーネントのバリデータ、コンバータおよびその他の属性の詳細は、『Oracle Fusion Middleware Oracle Application Development Framework Webユーザー・インタフェース開発者ガイド』の「入力コンポーネントの使用とフォームの定義」を参照してください。


    • ADF読取り専用フォーム: 「ADFフォーム」と同じですが、読取り専用outputTextコンポーネントが使用されます。このフォームはデータの表示を目的としているため、validatorタグは追加されません(コンバータは含まれます)。タイプDateの属性は、読取り専用フォームではoutputTextコンポーネントを使用します。すべてのコンポーネントはpanelLabelAndMessageコンポーネント内に置かれます。このコンポーネントには、label属性が移入されます。 panelLabelAndMessageコンポーネントは、panelFormLayoutコンポーネント内に配置されます。

    • ADF動的フォーム: バインディングが実行時に決定されるフォームを作成します。詳細は、3.8項「実行時に表示するデータを決定する動的フォームの使用」を参照してください。

  3. 「フォーム・フィールドの編集」ダイアログで、フォームを構成します。

    ユーザーがコレクション内の全データ・オブジェクト間を移動できるようにする、ナビゲーション・コントロールを含めることもできます。詳細は、3.4項「レンジ・ナビゲーションのフォームへの組入れ」を参照してください。 また、フォームの送信に使用する「送信」ボタンを含めることもできます。このボタンはHTMLフォームを発行し、フォームのデータをJSF/ADFページ・ライフサイクルの一部としてバインディングに適用します。このダイアログの使用方法に関する追加のヘルプを表示するには、「ヘルプ」をクリックします。すべてのUIコンポーネントは、panelFormLayoutコンポーネントの中に配置されます。

  4. ユーザーによるデータの更新が可能なフォームを作成する場合は、ここで、更新を実行するメソッドをドラッグ・アンド・ドロップする必要があります。詳細は、3.6項「既存レコードを編集するフォームの作成」を参照してください。

3.3.2 フォームの作成時の処理

「データ・コントロール」パネルからオブジェクトをフォームとしてドロップすることは、単一の属性をドロップするのと同じ効果があります。ただし、複数の属性バインディングおよび関連するUIコンポーネントが作成される点が異なります。UIコンポーネントの属性(valueなど)は、その属性のバインディング・オブジェクト(inputValueなど)のプロパティ、または対応するサービスで設定されるコントロール・ヒントの値にバインドされます。例3-5に、suppliersFindAllアクセッサ・コレクションをデフォルトADFフォームとしてドロップしてサプライヤの詳細の編集フォームを作成した場合にJSFページで生成されるコードの一部を示します。


注意:

関連付けられている構造定義ファイルで属性が非表示としてマークされている場合、対応するUIは作成されません。


例3-5 入力フォームのJSFページのコード

<af:panelFormLayout id="pfl1">
  <af:inputText value="#{bindings.supplierName.inputValue}"
                label="#{bindings.supplierName.hints.label}"
                required="#{bindings.supplierName.hints.mandatory}"
                columns="#{bindings.supplierName.hints.displayWidth}"
                maximumLength="#{bindings.supplierName.hints.precision}"
                shortDesc="#{bindings.supplierName.hints.tooltip}"
                id="it4">
    <f:validator binding="#{bindings.supplierName.validator}"/>
  </af:inputText>
  <af:inputText value="#{bindings.email.inputValue}"
                label="#{bindings.email.hints.label}"
                required="#{bindings.email.hints.mandatory}"
                columns="#{bindings.email.hints.displayWidth}"
                maximumLength="#{bindings.email.hints.precision}"
                shortDesc="#{bindings.email.hints.tooltip}"
                id="it3">
    <f:validator binding="#{bindings.email.validator}"/>
  </af:inputText>
  <af:inputText value="#{bindings.phoneNumber.inputValue}"
                label="#{bindings.phoneNumber.hints.label}"
                required="#{bindings.phoneNumber.hints.mandatory}"
                columns="#{bindings.phoneNumber.hints.displayWidth}"
                maximumLength="#{bindings.phoneNumber.hints.precision}"
                shortDesc="#{bindings.phoneNumber.hints.tooltip}"
                id="it1">
    <f:validator binding="#{bindings.phoneNumber.validator}"/>
  </af:inputText>
  <af:inputText value="#{bindings.supplierStatus.inputValue}"
                label="#{bindings.supplierStatus.hints.label}"
                required="#{bindings.supplierStatus.hints.mandatory}"
                columns="#{bindings.supplierStatus.hints.displayWidth}"
                maximumLength="#{bindings.supplierStatus.hints.precision}"
                shortDesc="#{bindings.supplierStatus.hints.tooltip}"
                id="it2">
    <f:validator binding="#{bindings.supplierStatus.validator}"/>
  </af:inputText>
. . .
</af:panelFormLayout>

注意:

バリデータ・タグとコンバータ・タグの詳細は、『Oracle Fusion Middleware Oracle Application Development Framework Webユーザー・インタフェース開発者ガイド』の「入力の検証および変換」を参照してください。


3.4 レンジ・ナビゲーションのフォームへの組入れ

ADFフォームを作成する際、ナビゲーション・コントロールの組込みを選択すると、データ・コントロールの既存のナビゲーション・ロジックにバインドされているADF Facesコマンド・コンポーネントが組み込まれます。この組込みロジックによって、ユーザーは、コレクション内のすべてのデータ・オブジェクト間を移動できるようになります。たとえば、図3-4は、suppliersFindAllアクセッサをドラッグし、ナビゲーションを使用するADFフォームとしてドロップした場合に作成されるフォームを示しています。

図3-4 フォーム内のナビゲーション

検索結果の詳細ページ内のナビゲーション・ボタン

3.4.1 フォームへのナビゲーション・コントロールの挿入方法

デフォルトでは、「データ・コントロール」パネルを使用してフォームを作成する際にナビゲーションの組込みを選択すると、「先頭へ」「最後へ」「前へ」および「次へ」の各ボタンが作成され、ユーザーがコレクション内を移動できるようになります。

また、既存のフォームにナビゲーション・ボタンを手動で追加できます。

ナビゲーション・ボタンを手動で追加する場合の手順:

  1. 操作の実行対象となるオブジェクトのコレクションに関連付けられる操作を「データ・コントロール」パネルから選択し、JSFページ上にドラッグします。

    たとえば、製品のコレクション内を移動できるようにする場合は、suppliersFindAllアクセッサに関連付ける「次へ」操作をドラッグします。図3-5に、suppliersFindAllアクセッサに関連付けられている操作を示します。

    図3-5 コレクションに関連付けられている操作

    DCPでのナビゲーション操作
  2. 次に表示されるポップアップ・メニューから「ADFボタン」または「ADFリンク」を選択します。


ヒント:

「先頭へ」「最後へ」「前へ」および「次へ」のすべてのボタンを一度にドロップすることもできます。これを行うには、対応するコレクションをドラッグし、ポップアップ・メニューから「移動」→「ADFナビゲーション・ボタン」を選択します。


3.4.2 コマンド・ボタンの作成時の処理

任意の操作をコマンド・コンポーネントとしてドロップすると、JDeveloperによって次の処理が行われます。

  • 関連付けられている操作について、ページ定義ファイルでアクション・バインディングが定義されます。

  • コレクションに部分ページ・レンダリングを使用するように、イテレータ・バインディングが構成されます。

  • コマンド・コンポーネント用のコードがJSFページに挿入されます。

3.4.2.1 組込みナビゲーション操作のアクション・バインディング

アクション・バインディングは、ビジネス・ロジックを実行します。たとえば、アクション・バインディング・オブジェクト上で組込みメソッドを起動できます。このような組込みメソッドは、イテレータやデータ・コントロール自体に対して作用し、「データ・コントロール」パネルに操作として表示されます。JDeveloperには、ユーザーによるコレクション内の前後のオブジェクトへの移動や最初または最後のオブジェクトへの移動を可能にするナビゲーション操作が用意されています。

アクション・バインディングがNextまたはPreviousなどのイテレータレベル・アクションにバインドされている場合、操作のアクション・バインディングには、値バインディングと同様にイテレータ・バインディングへの参照が含まれます。これらのタイプのアクションはイテレータによって実行されます。イテレータは現在のオブジェクトを判別するため、ナビゲーション・ボタンがクリックされたときに表示するオブジェクトが正しく判別されます。

アクション・バインディングはRequiresUpdateModelプロパティを使用して、アクションを実行する前にモデルを更新する必要があるかどうかを判別します。ナビゲーション操作の場合、デフォルトではこのプロパティはtrueに設定されています。つまり、ビュー・レイヤーでのすべての変更は、ナビゲーションを実行する前にモデルに移動する必要があります。例3-6に、ナビゲーション操作のアクション・バインディングを示します。

例3-6 操作アクション・バインディングのページ定義コード

<action IterBinding="CustomerInfoVO1Iterator" id="First"
         RequiresUpdateModel="true" Action="first"/>
<action IterBinding="CustomerInfoVO1Iterator" id="Previous"
        RequiresUpdateModel="true" Action="previous"/>
<action IterBinding="CustomerInfoVO1Iterator" id="Next"
        RequiresUpdateModel="true" Action="next"/>
<action IterBinding="CustomerInfoVO1Iterator" id="Last"
        RequiresUpdateModel="true" Action="last"/>

3.4.2.2 イテレータのRangeSize属性

イテレータ・バインディングにはrangeSize属性が含まれ、バインディングではこの属性を使用して、反復ごとにページで使用できるようにするデータ・オブジェクト数が決定されます。この属性は、データソース内のオブジェクト数がきわめて多い場合に役立ちます。イテレータ・バインディングでは、すべてのオブジェクトではなく、設定されている数のオブジェクトのみが返され、他のバインディングからアクセス可能になります。イテレータはレンジの最後に到達すると、次のセットにアクセスします。例3-7に、suppliersFindAllイテレータのデフォルトのレンジ・サイズを示します。

例3-7 イテレータのRangeSize属性

<accessorIterator MasterBinding="SessionEJBLocalIterator"
                  Binds="suppliersFindAll" RangeSize="25"
                  DataControl="SessionEJBLocal" BeanClass="model.Suppliers"
                  id="suppliersFindAllIterator" ChangeEventPolicy="ppr"/>

注意:

このrangeSize属性は、表コンポーネントのrows属性とは異なります。


デフォルトでは、rangeSize属性は25に設定されています。つまり、ユーザーは、25個のオブジェクトを表示でき、データソースにアクセスしなくても、このオブジェクト間を前後に移動できるということです。イテレータは、現在のオブジェクトを追跡します。ユーザーが新しいレンジを要求するボタンをクリックすると(たとえば、オブジェクト番号25で「次へ」ボタンをクリックすると)、関連付けられているメソッドがバインディング・オブジェクトによってイテレータに対して実行され、イテレータは別の25個のレコードのセットを取得します。その後、そのセットがバインディングによって使用されます。この設定は、必要に応じて変更できます。完全なレコード・セットを戻すには、-1に設定します。


注意:

「データ・コントロール」パネルを使用してナビゲーション可能なフォームを作成する場合、関連するイテレータのCacheResultsプロパティはtrueに設定されます。これにより、現在行情報などのイテレータの状態はリクエスト間でキャッシュされ、現在のオブジェクトを判別できるようになります。このプロパティがfalseに設定されている場合、ナビゲーションは機能しません。


表3-1に、データ・コントロールで提供される組込みナビゲーション操作と、操作の起動または操作にバインドされたイベントの実行の結果を示します。アクション・イベントの詳細は、『Oracle Fusion Middleware Oracle Application Development Framework Fusion開発者ガイド』の実行時に行われる処理とアクション・イベントおよびアクション・リスナーの動作方法に関する項を参照してください。

表3-1 組込みナビゲーション操作

操作 関連付けられているイテレータ・バインディングによる起動時の処理

先頭

現在のポインタを結果セットの先頭に移動します。

最後

現在のポインタを結果セットの最後に移動します。

現在のポインタを結果セットの前のオブジェクトに移動します。このオブジェクトが現在のレンジの外にある場合は、レンジ・サイズと同じオブジェクト数だけレンジが戻るようにスクロールされます。

現在のポインタを結果セットの次のオブジェクトに移動します。このオブジェクトが現在のレンジの外にある場合は、レンジ・サイズと同じオブジェクト数だけレンジが進むようにスクロールされます。

前のセット

レンジ・サイズ属性と同じオブジェクト数だけ、レンジを戻すように移動します。

次のセット

レンジ・サイズ属性と同じオブジェクト数だけ、レンジを進めるように移動します。


3.4.2.3 EL式を使用したナビゲーション操作へのバインド

ナビゲーション操作を使用してコマンド・コンポーネントを作成すると、コマンド・コンポーネントはpanelGroupLayoutコンポーネント内に配置されます。JDeveloperにより、ナビゲーション・コマンド・ボタンのactionListener属性を、指定された操作のアクション・バインディングのexecuteプロパティにバインドするEL式が作成されます。

実行時、アクション・バインディングは、コアのJUCtrlActionBinding実装クラスを拡張するFacesCtrlActionBindingクラスのインスタンスです。FacesCtrlActionBindingクラスにより、次のメソッドが追加されます。

  • public void execute(ActionEvent event): actionListenerプロパティで参照されるメソッドです(例: #{bindings.First.execute})。

    ユーザーがボタンをクリックすると、この式によって、イテレータに対してバインディングの操作が起動されます。たとえば、「先頭へ」コマンド・ボタンのactionListener属性は、Firstアクション・バインディングのexecuteメソッドにバインドされています。

  • public String outcome(): Actionプロパティで参照できます(例: #{bindings.Next.outcome})。

    移動先となる次のページを決定するJSFナビゲーションの結果として、メソッド・アクション・バインディングの結果(Stringに変換後)に使用できます。


    注意:

    アクション・バインディングでoutcomeメソッドを使用すると、ビューおよびコントローラのレイヤーとモデルが過度に緊密に結ばれるため、ほとんど使用されません。


操作の各アクション・バインディングには、enabledブール型プロパティが含まれます。このプロパティは、操作を起動しない場合には、Oracle ADFによってfalseに設定されます。デフォルトでは、JDeveloperがこの値にUIコンポーネントのdisabled属性をバインドして、コンポーネントを有効化するかどうかを指定します。たとえば、「先頭へ」ボタンのUIコンポーネントのdisabled属性の値は、次のとおりです。

#{!bindings.First.enabled}

この式は、バインディングが有効でない場合、常にtrueに評価されます。つまり、操作を起動しない場合に、ボタンが無効になります。この例では、最初のレコードが表示されている場合はいつでも、フレームワークがバインディングのenabledプロパティをfalseに設定するため、「先頭へ」ボタンが自動的に無効になります。これは、enabledFalseの場合は、常にdisabled属性がtrueに設定されるためです。enabledプロパティの詳細は、Oracle Fusion Middleware Oracle Application Development Framework Fusion開発者ガイドのOracle ADFバインディング・プロパティに関する付録を参照してください。

例3-8に、ナビゲーション操作ボタンに対してJSFページで生成されたコードを示します。ボタンのpartialSubmit属性の詳細は、『Oracle Fusion Middleware Oracle Application Development Framework Webユーザー・インタフェース開発者ガイド』の部分ページ・レンダリングの宣言的な有効化に関する項を参照してください。バインディングの自動部分ページ・レンダリングの詳細は、『Oracle Fusion Middleware Oracle Application Development Framework Fusion開発者ガイド』の自動部分ページ・レンダリングに関する項を参照してください。

例3-8 ADF操作にバインドされているナビゲーション・ボタンのJSFコード

<f:facet name="footer">
   <af:panelGroupLayout>
     <af:commandButton actionListener="#{bindings.First.execute}"
                       text="First"
                       disabled="#{!bindings.First.enabled}"
                       partialSubmit="true" id="cb1"/>
     <af:commandButton actionListener="#{bindings.Previous.execute}"
                       text="Previous"
                       disabled="#{!bindings.Previous.enabled}"
                       partialSubmit="true" id="cb2"/>
     <af:commandButton actionListener="#{bindings.Next.execute}"
                       text="Next"
                       disabled="#{!bindings.Next.enabled}"
                       partialSubmit="true" id="cb3"/>
     <af:commandButton actionListener="#{bindings.Last.execute}"
                       text="Last"
                       disabled="#{!bindings.Last.enabled}"
                       partialSubmit="true" id="cb4"/>
   </af:panelGroupLayoutr>
 </f:facet>

3.5 パラメータをとるメソッドを使用するフォームの作成

コンテンツを表示する前に、ページで情報を必要とする場合があります。このタイプのページの場合、パラメータをとるメソッドから返されるコレクションを使用してフォームを作成します。メソッドを実行するには、要求元のページがパラメータの値を指定する必要があります。

たとえば、productInfoページのフォームは、findProductById(Long)メソッドから返されるコレクションを使用して作成されます。すべての製品ではなく、その前のページでユーザーが選択した製品のみが返されます。前のページのツールバー・ボタンによって、製品のIDを指定するパラメータ(Long)が設定されます。コマンド・コンポーネントを使用したパラメータ値の設定の詳細は、3.5.4項「メソッドによるパラメータの設定について」を参照してください。

3.5.1 パラメータをとるメソッドを使用するフォームまたは表の作成方法

パラメータを必要とするフォームを作成する場合、返すレコードを決定するために、パラメータの値にアクセスできる必要があります。それらの値にアクセスするには、あるオブジェクトにパラメータ値を設定し、その後メソッドがそのオブジェクトにアクセスできるようなロジックを、別のページのコマンド・ボタンに追加します。たとえば、browse.jspxページで、「編集」ツールバー・ボタンによってpageFlowスコープに製品IDを設定します。製品情報を表示するフォームを作成するには、findProductById(Long)メソッドの戻りを使用します。このメソッドが、pageFlowスコープのパラメータにアクセスします。パラメータはここに格納されています。

始める前に:

セッションBeanに、フォームでの表示に必要な項目を返すメソッドを作成する必要があります。たとえば、findProductById(Long)メソッドがSupplierFacadeBean.javaクラスに追加されています。


ヒント:

サービスに行われた変更を「データ・コントロール」パネルに表示するには、パネルをリフレッシュする必要があります。パネルをリフレッシュするには、「リフレッシュ」アイコンをクリックします。


パラメータを使用するフォームまたは表を作成する手順:

  1. 「データ・コントロール」パネルから、パラメータをとるメソッドの戻りであるコレクションをドラッグし、任意のタイプのフォームとしてドロップします。

    たとえば、製品を編集するツールバー・ボタンをクリックすると表示されるフォームを作成するには、図3-6に示すように、Product戻りをドラッグ・アンド・ドロップします。

    図3-6 パラメータをとるカスタム・メソッドの戻り

    パラメータをとるメソッド戻り
  2. 「フォーム・フィールドの編集」ダイアログで、必要に応じてフォームを構成し、「OK」をクリックします。

    このダイアログの使用に関するヘルプを表示するには、「ヘルプ」をクリックします。

    メソッドがパラメータをとるため、「アクション・バインディングの編集」ダイアログが開き、パラメータの値を設定するよう求められます。

  3. アクション・バインディング・エディタで「値」フィールドの参照(「...」)アイコンをクリックし、EL式ビルダーを開いて各パラメータの値を入力します。パラメータの値を表すノードを選択します。

    たとえば、ツールバー・ボタンが、pageFlowスコープのproductIdパラメータ値を設定するsetActionListenerComponentを使用するとします。その値にアクセスするには、パラメータの値として#{pageFlowScope.ProductId}を使用します。

    このエディタでは、この値を使用して、メソッドが実行される際のパラメータを表すNamedData要素が作成されます。メソッドの戻りであるコレクションをドロップしているため、このメソッドは(コマンド・ボタンにバインドされているメソッドとは異なり)、関連付けられているイテレータがページのロード時に実行される際に実行されます。パラメータ値は、ページがレンダリングされる前に設定される必要があります。つまり、NamedData要素は、送信元ページの設定に関係なく、この値を取得する必要があるということです。

3.5.2 パラメータをとるメソッドを使用するフォームの作成時の処理

パラメータをとるメソッドの戻りを使用してフォームを作成すると、JDeveloperによって次の処理が行われます。

  • メソッドに対するアクション・バインディング、メソッドの結果に対するメソッド・イテレータ・バインディング、オブジェクトの各属性に対する属性バインディング、表の場合は表バインディングが作成されます。メソッドが必要とする各パラメータのNamedData要素の作成も行われます。

  • ADF Facesコンポーネントを使用するフォームのコードがJSFページに挿入されます。

例3-9に、findProductById(Long)メソッドをドロップすると作成されるアクション・メソッド・バインディングを示します。ここでは、productIdの値は、pageFlowScopeに格納されているProductId属性に設定されています。

例3-9 メソッド戻りのメソッド・アクション・バインディング

<bindings>
  <methodAction id="findProductById" RequiresUpdateModel="true"
                Action="invokeMethod" MethodName="findProductById"
                IsViewObjectMethod="false" DataControl="SupplierFacadeLocal"
                InstanceName="SupplierFacadeLocal.dataProvider"
                ReturnName="SupplierFacadeLocal.methodResults.findProductById_
                         SupplierFacadeLocal_dataProvider_findProductById_result">
    <NamedData NDName="productId" NDValue="#{pageFlowScope.ProductId}"
                       NDType="java.lang.Long"/>
  </methodAction>
...
</bindings>

NamedData要素は、要求元のページで設定されているとおり、pageFlowScopeproductIDとして評価されます。

3.5.3 実行時に行われる処理: メソッドのパラメータの設定

ユーザーがコマンド・ボタンをクリックすると実行されるメソッドとは異なり、フォームの作成に使用されるメソッドは、ページのロード時に実行されます。ページのデータを返すためにメソッドが実行される際、メソッドでNamedData要素のEL式が評価され、その値がパラメータとして使用されます。このようにして正しいデータを返すことができます。メソッドが複数のパラメータをとる場合、各パラメータが順に評価され、メソッドにパラメータが設定されます。

たとえば、ProductInfoページでは、ロード時にpageFlowスコープのProductIdパラメータの値が取得され、findProductById(Integer)メソッドで必要なパラメータの値として設定されます。メソッドが実行されると、パラメータの値に一致するレコードのみが返されます。メソッドの戻りをドロップしてフォームを作成したため、その戻りが表示される製品です。

3.5.4 メソッドによるパラメータの設定について

あるページでのアクションによって、アプリケーションの機能の決定に使用されるパラメータを設定する必要が生じる場合があります。たとえば、あるページに、パラメータ値がfalseの場合にのみコンポーネントが表示される別のページに移動するコマンド・ボタンを作成できます。

ページ間でこのパラメータを渡す場合やパラメータ値のチェックに使用するメソッドを含める場合には、マネージドBeanを使用できます。コマンド・ボタン内にネストしている、typeプロパティがactionに設定されているsetPropertyListenerコンポーネントを使用して、パラメータを設定します。メソッドを使用したパラメータの設定の詳細は、『Oracle Fusion Middleware Oracle Application Development Framework Fusion開発者ガイド』のコマンド・コンポーネントを使用したパラメータ値の設定に関する項を参照してください。


注意:

タスク・フローを使用している場合、タスク・フローのパラメータ渡しメカニズムを使用できます。詳細は、『Oracle Fusion Middleware Oracle Application Development Framework Fusion開発者ガイド』の「タスク・フローのパラメータの使用」を参照してください。


3.5.5 パラメータのかわりのコンテキスト・イベントの使用について

ページまたはページ内のリージョンで、ページの別の場所または別のリージョンの情報を必要する場合があります(リージョンの詳細は、『Oracle Fusion Middleware Oracle Application Development Framework Fusion開発者ガイド』のタスク・フローのリージョンとしての使用に関する項を参照してください)。情報を取得するためにパラメータを渡すことは可能ですが、それはパラメータが既知であり、EL式でページにアクセスできる入力である場合のみ意味を持ちます。また、パラメータ値が変化した場合にタスク・フローを再起動する必要があるときに、パラメータは便利です。

ただし、複数のページ・フラグメントを持つタスク・フローがあり、ページ・フラグメントには、フロー内のあるページへの入力として使用できる様々な興味深い値が含まれているとします。パラメータを使用して値を渡す場合、タスク・フローはすべてのフラグメントの興味深い各値を結合するための出力パラメータを公開する必要があります。そのかわり、必要な情報を含む各フラグメントに対し、ページを送信すると発生するコンテキスト・イベントを定義できます。情報を必要とするページまたはフラグメントは、様々なイベントをサブスクライブし、イベントを介して情報を取得できます。

コンテキスト・イベントは、ページ定義ファイルを使用して作成および構成できます。詳細は、『Oracle Fusion Middleware Oracle Application Development Framework Fusion開発者ガイド』のコンテキスト・イベントの作成に関する項を参照してください。

3.6 既存レコードを編集するフォームの作成

ユーザーが現在のデータを編集し、その変更をデータソースにコミットするためのフォームを作成できます。これを行うには、コレクションに関連付けられたデータ・レコードを変更できるメソッドを使用して、コマンド・ボタンを作成します。たとえば、デフォルトのmergeSuppliers(Suppliers)メソッドを使用して、ユーザーが仕入先を更新できるボタンを作成できます。

ページがバインド・タスク・フローの一部ではない場合、コレクションに関連付けられているマージまたは永続化のメソッドを使用して、変更をコレクションにマージする必要があります(この2つの違いについては、3.6.3項「マージ・メソッドと永続化メソッドとの違いについて」を参照してください)。ページが、バインド・タスク・フロー内のトランザクションの一部である場合、commit操作とrollback操作を使用して、タスク・フロー・リターン・アクティビティのトランザクションを解決します。詳細は、『Oracle Fusion Middleware Oracle Application Development Framework Fusion開発者ガイド』のタスク・フロー・リターン・アクティビティの使用に関する項を参照してください。

3.6.1 編集フォームの作成方法

フォームでメソッドを使用するには、操作と同じ手順を実行します。

編集フォームの作成方法:

  1. 「データ・コントロール」パネルから、フォームを作成するコレクションをドラッグし、ポップアップ・メニューから「ADFフォーム」を選択します。

    これにより、inputTextコンポーネントを使用し、フィールドのデータを編集可能なフォームが作成されます。

  2. 操作の実行対象となるオブジェクトのコレクションに関連付けられるマージ・メソッドまたは永続化メソッドを「データ・コントロール」パネルから選択し、JSFページ上にドラッグします。

    たとえば、仕入先のレコードを更新できるようにし、そのインスタンスを再度使用しない場合、mergeSuppliers(Suppliers)メソッドをドラッグします。マージ・メソッドと永続化メソッドの違いについては、3.6.3項「マージ・メソッドと永続化メソッドとの違いについて」を参照してください。

  3. 次に表示されるポップアップ・メニューから「ADFボタン」または「ADFリンク」を選択します。

  4. 「アクション・バインディングの編集」ダイアログで、メソッドのパラメータに値を移入する必要があります。マージ・メソッド(およびその他のデフォルト・メソッド)の場合、これが更新されるオブジェクトです。

    1. 「パラメータ」セクションで、「値」ドロップダウン・リストを使用して「EL式ビルダーの表示」を選択します。

    2. 式ビルダーで、アクセッサのイテレータのノードを展開して「currentRow」ノードを展開し、「dataProvider」を選択します。

      これによって、アクセッサのイテレータで現在の行の値と評価されるEL式が作成されます。

    3. 「OK」をクリックします。

    たとえば、suppliersFindAllアクセッサ・コレクションを使用してフォームを作成した場合、JDeveloperによってsuppliersFindAllIteratorという名前のaccessorIteratorバインディングが作成されます。図3-7に示すように、そのイテレータの下の現在の行のdataProviderを選択する必要があります。この参照は、パラメータ値が、現在フォームに表示されている行の値に解決されることを表します。

    図3-7 suppliersFindAllIteratorバインディングの現在の行のdataProvider

    suppliersFindAllIteratorの現在の行のdataProvider

    注意:

    ページが、バインド・タスク・フロー内のトランザクションの一部の場合、マージ・メソッド(または他のデフォルト・メソッド)からボタンを作成するかわりに、タスク・フロー・リターン・アクティビティの作成時に、トランザクション解決の値としてそのメソッドを設定します。詳細は、『Oracle Fusion Middleware Oracle Application Development Framework Fusion開発者ガイド』のタスク・フロー・リターン・アクティビティの使用に関する項を参照してください。


3.6.2 値を変更するメソッドの使用時の処理

メソッドをコマンド・ボタンとしてドロップすると、JDeveloperによって次の処理が行われます。

  • メソッドのメソッド・バインディングが定義されます。メソッドがパラメータをとる場合は、パラメータ値を保持するNamedData要素がJDeveloperによって作成されます。NamedData要素の詳細は、3.5.3項「実行時に行われる処理: メソッドのパラメータの設定」を参照してください。

  • ADF Facesコマンド・コンポーネント用のコードがJSFページに挿入されます。3.6.2.2項「EL式を使用したメソッドへのバインド」で説明されているとおり、このコードは、他のどのコマンド・ボタンのコードとも同じです。ただし、このボタンは、操作に対するアクション・バインディングのexecuteメソッドではなく、ドロップされたメソッドに対するアクション・バインディングのexecuteメソッドにバインドされます。

3.6.2.1 メソッド・バインディング

メソッドからボタンを作成する場合、組込み操作からボタンを作成する場合と同様に、JDeveloperによってメソッドに対するアクション・バインディングが作成されます。例3-10に、mergeSuppliers(Suppliers)メソッドをドロップした場合に作成されるアクション・バインディングを示します。

例3-10 イテレータによって使用されるアクション・バインディングのページ定義コード

<bindings>
  <methodAction id="mergeSuppliers" RequiresUpdateModel="true"
                Action="invokeMethod" MethodName="mergeSuppliers"
                IsViewObjectMethod="false" DataControl="SessionEJBLocal"
                InstanceName="SessionEJBLocal.dataProvider"
                ReturnName="SessionEJBLocal.methodResults.mergeSuppliers_
                            SessionEJBLocal_dataProvider_persistSuppliers_result">
      <NamedData NDName="suppliers" NDType="model.Suppliers"/>
    </methodAction>
</bindings>

この例では、アクション・プロパティ値がinvokeMethodであるため、バインディングがアクセスされると、メソッドが起動されます。

パラメータをとるメソッドをJSFページにドロップすると、JDeveloperによって各パラメータに対してNamedData要素も作成されます。これらの要素は、メソッドのパラメータを表します。たとえば、mergeSuppliers(Suppliers)メソッドのアクション・バインディングには、Suppliersパラメータに対するNamedData要素が含まれます。

3.6.2.2 EL式を使用したメソッドへのバインド

ナビゲーション操作を使用してコマンド・ボタンを作成するときと同様に、メソッドを使用してコマンド・ボタンを作成すると、JDeveloperによってactionListener属性を使用して、ボタンがメソッドにバインドされます。ボタンは、指定されたメソッドのアクション・バインディングのexecuteプロパティにバインドされます。このバインディングによって、バインディングのメソッドがビジネス・サービスで起動されます。actionListener属性の詳細は、『Oracle Fusion Middleware Oracle Application Development Framework Fusion開発者ガイド』の実行時に行われる処理とアクション・イベントおよびアクション・リスナーの動作方法に関する項を参照してください。


ヒント:

アクション・バインディングのexecuteメソッドにボタンをバインドするかわりに、executeメソッドを上書きするバッキングBean内のメソッドにボタンをバインドできます。そうすることで、元のメソッドの実行前か実行後に、ロジックを追加できるようになります。詳細は、3.6.4項「宣言メソッドの上書きについて」を参照してください。


ナビゲーション操作のように、ボタンのdisabledプロパティは、EL式を使用してボタンを表示するかどうかを決定します。例3-11に、コマンド・ボタンのmergeSuppliers(Suppliers)メソッドへのバインドに使用されるEL式を示します。

例3-11 コマンド・ボタンをメソッドにバインドするためのJSFコード

<af:commandButton actionListener="#{bindings.mergeSupplier.execute}"
                  text="mergeSupplier"
                  disabled="#{!bindings.mergeSupplier.enabled}"
                  id="cb1"/>

ヒント:

UIコンポーネントをページにドロップすると、それより前にドロップされた同じタイプのコンポーネントの数に基づいて、JDeveloperによってIDが自動的に付けられます(cb1cb2など)。このIDは、説明的なものに変更できます。特に、ページの複数のUIコンポーネントに対するメソッドを含むバッキングBeanで参照する必要がある場合は、変更した方が適しています。


3.6.3 マージ・メソッドと永続化メソッドとの違いについて

セッションBeanを作成する際に、構造化オブジェクトのマージ・メソッドと永続化メソッドを公開するよう選択した場合、それらのメソッドが「データ・コントロール」パネルに表示され、ユーザーがオブジェクトの現在のインスタンスをマージしたり、永続化できるボタンの作成に使用できます。どちらを使用するかは、更新が行われた後でページとインスタンスとの対話が必要かどうかで決まります。インスタンスを使用し続ける必要がある場合、永続化メソッドを使用します。

マージ・メソッドは、JPA EntityManager.mergeメソッドの実装です。このメソッドは、現在のインスタンスを取得してコピーし、そのコピーをPersistenceContextに渡します。その後、元のオブジェクトではなく、その永続化されたエンティティへの参照が返されます。つまり、それ以降そのインスタンスに行われる変更は、マージ・メソッドを再度コールしないかぎり永続化されないということです。

永続化メソッドは、JPA EntityManager.persistメソッドの実装です。マージ・メソッド同様、このメソッドは、現在のインスタンスをPersistenceContextに渡します。ただし、コンテキストによってそのインスタンスの管理が続けられるため、以降の更新はコンテキスト内のインスタンスに行われます。

3.6.4 宣言メソッドの上書きについて

操作またはメソッドをコマンド・ボタンとしてドロップすると、JDeveloperによって操作またはメソッドのexecuteメソッドにそのボタンがバインドされます。ただし、既存のロジックの前または後に、ロジックの追加が必要になる場合もあります。JDeveloperを使用すると、バインディング・コンテナにアクセスするマネージドBeanにメソッドおよびプロパティを新規作成することにより、宣言的操作にロジックを追加できます。デフォルトでは、この生成されたコードによって、操作またはメソッドが実行されます。その後、このコードの前か後にロジックを追加できます。元の操作またはメソッドのexecuteプロパティではなく、この新規メソッドにコマンド・コンポーネントが自動的にバインドされます。その後、ユーザーがボタンをクリックすると、新規メソッドが実行されます。詳細は、『Oracle Fusion Middleware Oracle Application Development Framework Fusion開発者ガイド』の宣言メソッドの上書きに関する項を参照してください。

3.7 入力フォームの作成

ユーザーが新規レコードの情報を入力し、そのレコードをデータソースにコミットするためのフォームを作成できます。入力フォームを含むページが表示される前に、Create操作をコールするメソッド・アクティビティを含むタスク・フローを使用する必要があります。このメソッド・アクティビティによって空白行が行セットに挿入されます。その後、ユーザーはフォームを使用して空白行にデータを移入できます。


ヒント:

タスク・フローの詳細は、『Oracle Fusion Middleware Oracle Application Development Framework Fusion開発者ガイド』のADFタスク・フローの作成に関するパートを参照してください。


たとえば、Supplierモジュールに、ユーザーによる住所の作成が可能な新規フォームを作成します。createAddressメソッド・アクティビティを含むcreate-address-task-flowタスク・フローを作成します。このメソッド・アクティビティは、addressesアクセッサに対してCreate操作をコールします。その後、制御がcreateAddressビュー・アクティビティに渡され、図3-8に示すような、ユーザーが新しい住所を入力できるフォームが表示されます。

図3-8 住所の作成

アドレス入力フォーム

注意:

アプリケーションでタスク・フローを使用しない場合は、タスク・フローのメソッド・アクティビティと同様の方法で、コール元のページでcreate操作を起動する必要があります。たとえば、コール元のページ上のコマンド・ボタンに関連付けられたイベント・ハンドラ内にアプリケーション・ロジックを指定できます。


3.7.1 タスク・フローを使用した入力フォームの作成方法

バインド・タスク・フロー内に入力フォームを作成し、適切なトランザクションの処理が行われるようにします。

始める前に:

フォームとCreate操作を実行するメソッド・アクティビティの両方を含むバインド・タスク・フローを作成する必要があります。タスク・フローによって新規トランザクションが開始される必要があります。手順は、『Oracle Fusion Middleware Oracle Application Development Framework Fusion開発者ガイド』のタスク・フローの作成に関する項を参照してください。

入力フォームの作成手順:

  1. バインド・タスク・フローにメソッド・アクティビティを追加します。このアクティビティに、フォームを作成するアクセッサに関連付けられているCreate操作を実行させます。メソッド・アクティビティを使用する手順は、『Oracle Fusion Middleware Oracle Application Development Framework Fusion開発者ガイド』のメソッド・コール・アクティビティの使用に関する項を参照してください。

    たとえば、ユーザーによる住所の作成が可能なフォームを作成する場合、メソッド・アクティビティに、addressesアクセッサに関連付けられているCreate操作を実行させます。

  2. プロパティ・インスペクタで、fixed-outcomeプロパティに文字列を入力します。たとえば、fixed-outcome値としてcreateと入力します。

  3. 入力フォームのページを表すビュー・アクティビティを追加します。ビュー・アクティビティの追加の詳細は、『Oracle Fusion Middleware Oracle Application Development Framework Fusion開発者ガイド』のビュー・アクティビティの使用に関する項を参照してください。

  4. 制御フロー・ケースをメソッド・アクティビティからビュー・アクティビティに追加します。プロパティ・インスペクタで、手順2で設定したメソッド・アクティビティのfixed-outcomeプロパティの値を、制御フロー・ケースのfrom-outcomeの値として入力します。

  5. 設計エディタでビュー・アクティビティのページを開き、「データ・コントロール」パネルから、新しいレコードの作成にフォームを使用するコレクションをドラッグし、ポップアップ・メニューから「ADFフォーム」を選択します。

    たとえば、住所を作成するフォームの場合、「データ・コントロール」パネルから、addressesアクセッサ・コレクションをドラッグします。


    ヒント:

    データベースにコミットする前に、ユーザーが複数のエントリを作成できるようにする場合、次のようにします。

    1. タスク・フローで、ビュー・アクティビティからメソッド・アクティビティに戻る別の制御フロー・ケースを追加し、from-outcomeメソッドの値を入力します。たとえば、createAnotherと入力します。

    2. コンポーネント・パレットからコマンド・コンポーネントをページにドラッグ・アンド・ドロップし、action属性を、先ほど作成したfrom-outcomeに設定します。これによって、タスク・フローはメソッド・アクティビティに戻り、Create操作を再起動します。


  6. タスク・フローに、リターン・アクティビティを追加します。このリターン・アクティビティでは、データ・コントロールに対してコミット操作を実行する必要があります。この手順は、『Oracle Fusion Middleware Oracle Application Development Framework Fusion開発者ガイド』のタスク・フロー・リターン・アクティビティの使用に関する項を参照してください。


    ヒント:

    commit操作を実行するリターン・アクティビティを設定し、アクティビティでエラーが表示される場合、トランザクションを開始するようタスク・フロー自体が設定されていないことが原因である可能性があります。そのように設定する必要があります。詳細は、『Oracle Fusion Middleware Oracle Application Development Framework Fusion開発者ガイド』のトランザクションの管理に関する項を参照してください。


  7. 制御フロー・ケースをビュー・アクティビティからリターン・アクティビティに追加します。fixed-outcome属性をテキスト文字列に設定します。たとえば、returnに設定します。

  8. コンポーネント・パレットから、リターン・アクティビティの起動に使用されるボタンまたは他のコマンド・コンポーネントをドラッグ・アンド・ドロップします。action属性を、手順7で作成したfixed-outcomeに設定されているテキスト文字列に設定します。

3.7.2 タスク・フローを使用した入力フォームの作成時の処理

ADFフォームを使用して入力フォームを作成すると、JDeveloperによって次の処理が行われます。

  • メソッド・アクティビティのページ定義に、アクセッサのイテレータ・バインディングおよびCreate操作のアクション・バインディングが作成されます。Create操作は、行を行セットに作成し、データソースに入力されたデータを移入します。その他のフォームに関しては、ページのページ定義に、返されるコレクションのイテレータ・バインディングと、コレクション内のオブジェクトの各属性に対する属性バインディングが作成されます。

  • ADF Faces inputTextコンポーネント、および操作の場合はcommandButtonコンポーネントを使用して、JSFページにフォームのコードが挿入されます。

たとえば、図3-8に示すフォームは、メイン・ページの「Create Address」リンクをクリックすると表示されます。このリンクによって、新規住所のデータを入力できるフォームに移動します。住所を作成したら、「Save」ボタンをクリックすると、メイン・ページに戻ります。図3-9に、newAddressメソッド・アクティビティを含むcreate-address-task-flowタスク・フローを示します。

図3-9 入力フォーム用のタスク・フロー

入力フォーム用のタスク・フロー

例3-12に、メソッド・アクティビティのページ定義ファイルを示します。

例3-12 Creationメソッド・アクティビティのページ定義コード

<executables>
  <iterator Binds="root" RangeSize="25" DataControl="SupplierFacadeLocal"
            id="SupplierFacadeLocalIterator"/>
  <accessorIterator MasterBinding="SupplierFacadeLocalIterator"
                    Binds="addresses" RangeSize="25"
                    DataControl="SupplierFacadeLocal"
                    BeanClass="oracle.fodemo.supplier.model.Addresses"
                    id="addressesIterator"/>
</executables>
<bindings>
  <action IterBinding="addressesIterator" id="Create"
          RequiresUpdateModel="true" Action="createRow"/>
</bindings>

3.7.3 実行時に行われる処理: メソッド・アクティビティからのCreateアクション・バインディングの起動

newAddressメソッド・アクティビティにアクセスすると、Createアクション・バインディングが起動され、CreateInsertRow操作が実行されてコレクション用に空白の新規インスタンスが作成されます。メソッド・アクティビティからビュー・アクティビティへのルーティング中、メソッド・アクティビティのバインディング・コンテナは必須属性の検証をスキップするため、空白のインスタンスがページ上のフォームに表示できます。

3.8 実行時に表示するデータを決定する動的フォームの使用

ADF Facesで提供されている動的コンポーネントのライブラリには、「データ・コントロール」パネルからドロップできる動的フォームと動的表ウィジェットが含まれています。動的コンポーネントは、すべてのバインディング・メタデータが実行時に作成される点が標準コンポーネントと異なります。バインディングのこの動的作成により、コントロールをページにドロップする際に「フォーム・フィールドの編集」ダイアログで情報を構成するのではなく、エンティティの属性のコントロール・ヒントを使用して表示情報を設定できます。その結果、データの表示方法を変更する場合、構造定義ファイルで表示方法を変更するだけで、そのJavaオブジェクトにバインドされているすべての動的コンポーネントの表示が、変更を反映するよう変更されます。標準コンポーネントでは、表示属性(順序、属性のグループ化など)を変更する場合、データが表示されるページごとに変更する必要があります。

たとえば、Suppliersモジュールでは、supplierName属性とsupplierID属性をフォームの上部(または表の左端の列)にグループ化し、supplierStatusをフォームの下部(または表の右端の列)にグループ化し、emailphoneNumberをフォームまたは表の中央にグループ化するSuppliers Javaオブジェクトに対して、「カテゴリ」および「フィールド順」属性ヒントを設定できます。

図3-10は、この方法でコントロール・ヒントが設定されたSupplierコレクションをドラッグ・アンド・ドロップして作成される動的フォームの実行時を示しています。

図3-10 Javaオブジェクトのメタデータに設定されたヒントに基づいた動的フォームの表示

サプライヤ詳細動的フォーム

3.8.1 動的フォームの使用方法

動的フォームを使用するには、まず対応するJavaオブジェクトのコントロール・ヒント(特に順序ヒントとグループ化ヒント)を構造ファイルで設定する必要があります。次に、動的コンポーネントのライブラリをインポートします。その後、動的フォームまたは動的表ウィジェットをページにドロップできます。

始める前に:

関連付けられているJavaオブジェクトの属性にカテゴリとフィールド順のコントロール・ヒントを構造ファイルで設定する必要があります。

たとえば、図3-10の動的フォームの場合、次のようにしてsupplierIdsupplierNamephoneNumberemailおよびsupplierStatus属性のカテゴリとフィールド順のコントロール・ヒントを設定します。

  1. 「カテゴリ」フィールドにStringを入力します。

    同じStringを、この属性とともに表示されるグループ内の他の属性の「カテゴリ」値に使用します。たとえば、phoneNumberemailの両属性の「カテゴリ」値はcontactです。

  2. 「フィールド順」に、この属性が表示されるグループ内の場所を表す数値を入力します。

    たとえば、phoneNumberの「フィールド順」値は1で、email属性の値は2です。

コントロール・ヒントの作成手順は、『Oracle Fusion Middleware Oracle Application Development Framework Fusion開発者ガイド』のビュー・オブジェクトの属性コントロール・ヒントの定義に関する項を参照してください。

動的コンポーネントを使用する手順:

  1. まだ組み込まれていない場合は、動的コンポーネント・ライブラリをインポートします。

    1. アプリケーション・ナビゲータで、動的コンポーネントが使用されるビュー・プロジェクトを右クリックし、ポップアップ・メニューから「プロジェクト・プロパティ」を選択します。

    2. 「プロジェクト・プロパティ」ダイアログで、「JSPタグ・ライブラリ」ノードを選択します。

    3. 「JSPタグ・ライブラリ」ページで「追加」をクリックします。

    4. 「タグ・ライブラリの選択」ダイアログで、ADF動的コンポーネントを選択し、「OK」をクリックします。

    5. 「JSPタグ・ライブラリ」ページで「OK」をクリックします。

  2. コレクションを「データ・コントロール」パネルからページにドラッグし、ポップアップ・メニューから「フォーム」「ADF動的フォーム」を選択します。


    ヒント:

    動的コンポーネントがリストされない場合は、ライブラリがプロジェクトにインポートされていません。手順1を繰り返してください。


  3. プロパティ・インスペクタで「カテゴリ」フィールドに次のように入力します。

    • 「カテゴリ」: フォームに表示する最初のグループに対する「カテゴリ」UIヒントの値として使用される文字列を入力します。たとえば、図3-10では、「カテゴリ」値はidです。

    • 編集可能: データを編集可能にする(デフォルト)場合、trueと入力します。データを読取り専用にする場合、falseと入力します。

  4. フォームに表示するグループごとに、手順6および7を繰り返します。たとえば、図3-10のフォームは、実際にはカテゴリid用、カテゴリcontact用、カテゴリstatus用の3つの異なるフォームで構成されています。

3.8.2 動的コンポーネント使用時の処理

動的フォームをドロップすると、イテレータへのバインディングのみが作成されます。例3-13に、supplierコレクションをドロップすると作成される1つの動的フォーム・コンポーネントを含むページのページ定義を示します。属性バインディングは作成されないことに注意してください。

例3-13 動的フォームのページ定義コード

<pageDefinition xmlns="http://xmlns.oracle.com/adfm/uimodel"
                version="11.1.1.53.2" id="DynamicFormPageDef"
                Package="package.pageDefs">
  <parameters/>
  <executables>
    <iterator Binds="root" RangeSize="25"
              DataControl="SupplierFacadeLocal"
              id="SupplierFacadeLocalIterator"/>
    <accessorIterator MasterBinding="SupplierFacadeLocalIterator"
                      Binds="supplier" RangeSize="25"
                      DataControl="SupplierFacadeLocal"
                      BeanClass="oracle.fodemo.supplier.model.Supplier"
                      id="supplierIterator"/>
  </executables>
  <bindings/>
</pageDefinition>

JDeveloperによって、ドロップされたフォームごとに、動的フォーム・タグを含むformタグが挿入されます。例3-14に示すように、formタグの値はイテレータ・バインディングにバインドされます。このバインディングにより、フォーム全体がイテレータから戻されたデータにバインドされます。各属性の表示プロパティは個別に設定できません。また、JSFページで属性を直接並び替えることもできません。

例3-14 動的フォームのJSFページ・コード

<af:document>
  <af:messages/>
  <af:form>
    <dynamic:form value="#{bindings.supplierIterator}" id="f1"
                  category="id"/>
    <dynamic:form value="#{bindings.supplierIterator}" id="f2"
                  category="contact"/>
    <dynamic:form value="#{bindings.supplierIterator}" id="f3"
                  category="status"/>  </af:form>
</af:document>

ヒント:

フォームの機能に影響する特定のプロパティを設定できます。たとえば、アップロードに使用できるフォームの作成、レンダリング・プロパティの設定、部分トリガーの設定などが可能です。これを行うには、構造ウィンドウのaf:formタグを選択し、プロパティ・インスペクタを使用して必要なプロパティを設定します。


3.8.3 実行時に行われる処理: 属性値の動的な決定方法

動的コンポーネントを含むページがレンダリングされると、設計時に「データ・コントロール」パネルから項目をドロップしたときと同様に、バインディングが作成されます。ただし、バインディングは実行時に作成されます。詳細は、第3.3.2項「フォームの作成時の処理」を参照してください。


ヒント:

バインディングは実行時に作成される必要があるため、多少のパフォーマンス・ヒットがありますが、ビュー・オブジェクトの構造が変更されてもJSFページを再生成および再コンパイルする必要がないため、パフォーマンス・ゲインもあります。


3.8.4 動的フォームのコンバータについて

デフォルトでは、動的フォームを作成すると、必要なコンバータがあれば動的に作成され、コンバータのパターン文字列は、ビュー・オブジェクトにおける属性定義に関するフォーマット・ヒントに設定されます。

指定したJava型の属性に対するコンバータに代替フォーマット文字列を使用する場合、それを行うには、カスタム・コンバータを作成し、faces-config.xmlファイルに登録して、その型の属性に使用されるようにします。例3-15は、java.sql.Date属性に対するコンバータのfaces-config.xmlエントリを示しています。

例3-15 カスタム・コンバータのfaces-config.xmlエントリ

<converter>
   <display-name>Date Time Converter</display-name>
   <converter-for-class>java.sql.Date</converter-for-class>
   <converter-class>sample.apps.view.DateTimeConverter</converter-class>
</converter>

作成するカスタム・コンバータでは、(org.apache.myfaces.trinidadinternal.convert.DateTimeConverterのような) ADF FacesまたはTrinidadのコンバータ・クラスを拡張し、getPattern()メソッドを実装する必要があります。カスタム・コンバータの作成の詳細は、『Oracle Fusion Middleware Oracle Application Development Framework Webユーザー・インタフェース開発者ガイド』のカスタムJSFコンバータの作成に関する項 Converters"を参照してください。

動的フォームは、faces-config.xmlエントリで指定されたJava型に基づいて、コンバータを検索します。ビュー・オブジェクトにおける属性定義でフォーマット・ヒントが指定されている場合、そのヒントはコンバータ上でパターンとして使用されます。そうでない場合、パターンには手をつけず、コンバータのgetPattern()メソッドで返されるものからのデフォルトのパターンが使用されます。

3.9 フォーム上のUIコンポーネントおよびバインディングの変更

「データ・コントロール」パネルを使用してフォーム(動的フォームを除く)を作成すると、属性の削除、表示順序の変更、データの表示に使用するコンポーネントの変更、およびコンポーネントのバインド先の属性の変更を実行できます。

既存のUIコンポーネントとバインディングの変更の詳細は、『Oracle Fusion Middleware Oracle Application Development Framework Fusion開発者ガイド』のフォーム上のUIコンポーネントおよびバインディングの変更に関する項を参照してください。