Oracle® Fusion Middleware Oracle Application Development Framework Webユーザー・インタフェース開発者ガイド 11gリリース1 (11.1.1.7.0) B52029-07 |
|
前 |
次 |
この章では、ADF Facesコンポーネントに用意されている部分ページ・レンダリング機能を使用して、ページ全体ではなく、ページの一部を再レンダリングする方法について説明します。
この章では、次の項目について説明します。
Ajax(Asynchronous JavaScript and XML)は、対話型Webアプリケーションを作成するためのWeb開発手法で、Webページ全体を再レンダリングせずに少量のデータを内部的にサーバーと交換するため、Webページのレスポンスが向上します。その結果、Webページの対話性、速度および使い勝手が向上します。
ADF Facesでは、Ajaxの部分ページ・レンダリング動作を実現する機能を部分ページ・レンダリング(PPR)と呼びます。PPRを使用すると、ページ全体を再レンダリングせずにページ上の特定のコンポーネントをレンダリングできます。たとえば、ユーザーが入力コンポーネントで選択または入力した内容を出力コンポーネントで表示したり、コマンド・リンクまたはボタンでによって、ページ全体を再レンダリングせずにページ上の別のコンポーネントを再レンダリングできます。
PPRが機能するには、その中のコンポーネントでのみライフサイクルが実行される境界をページで設定する必要があります。境界を判断するために、処理するコンポーネントのルートをフレームワークに通知する必要があります。ルート・コンポーネントは、次の2つの方法で識別されます。
イベント: 特定のイベントはルートであるコンポーネントを示します。たとえば、showDetail
コンポーネントを展開または縮小する(8.9項「コンテンツの動的な表示および非表示」を参照)と送信される表示イベントは、showDetail
コンポーネントがルートであることを示します。showDetail
コンポーネントを展開または縮小すると、このコンポーネントでのみライフサイクルが実行されます。ルート・コンポーネントを識別するイベントの他の例には、ツリーのノード展開時の表示イベントまたは表のソート・イベントがあります。
コンポーネント: 特定のコンポーネントは境界として認識されるため、ルート・コンポーネントになります。たとえば、フレームワークでは、ポップアップ・ダイアログが境界と認識されます。ダイアログ内でトリガーされたイベントに関係なく、ダイアログ外のコンポーネントでライフサイクルは実行されません。ポップアップでのみ実行されます。
ビルトインPPR機能以外に、クロスコンポーネント・レンダリング(あるコンポーネントがトリガーとして機能し、別のコンポーネントがリスナーとして機能するように依存性を設定可能)を使用するようにコンポーネントを構成できます。トリガー・コンポーネントでイベントが発生すると、リスナー・コンポーネントとリスナーの子コンポーネントでのみがライフサイクルが実行され、リスナー・コンポーネントと子のみが再レンダリングされます。クロスコンポーネント・レンダリングは、宣言的に実装できます。ただし、デフォルトでは、トリガー・コンポーネントからのすべてのイベントでPPRが実行されます(表などの一部のコンポーネントでは、イベントのサブセットでのみ部分ターゲットがトリガーされます)。PPRを起動するイベントを厳密に制御する必要がある場合、またはターゲットを決めるロジックを使用する場合は、プログラムでPPRを実装できます。
ヒント: アプリケーションでFusionテクノロジ・スタックを使用する場合、任意のページで自動部分ページ・レンダリング機能を有効にできます。これによって、バックエンド・ビジネス・ロジックの結果として値が変更されるコンポーネントが自動的に再レンダリングされます。詳細は、『Oracle Fusion Middleware Oracle Application Development Framework Fusion開発者ガイド』の自動部分ページ・レンダリングに関する項を参照してください。 |
また、ADF FacesアプリケーションでPPRをナビゲーションに使用できます。標準JSFアプリケーションでは、あるページから次のページへナビゲートすると、新しいページをレンダリングする必要があります。AJAX式のコンポーネントを使用している場合、異なるJavaScriptライブラリとスタイルシートのダウンロードに時間がかかるため、これによってオーバーヘッドが生じる可能性があります。このようなコストのかかるオーバーヘッドを避けるため、ADF Facesアーキテクチャでは、必要に応じてページ全体の遷移をシミュレートできますが、実際は1つのページにいるため、JavaScriptコードとスキン・スタイルを再ロードする必要がありません。
注意: PPRが機能するには、ブラウザでJavaScriptが有効になっている必要があります。 |
最も単純なクロスコンポーネント・レンダリングを使用した場合、トリガー・コンポーネントと呼ばれるコンポーネントでイベントが発生すると、ターゲット・コンポーネントと呼ばれるコンポーネントが再レンダリングされます。
たとえば、図7-1に示すように、File Explorerアプリケーションには「検索」パネルに検索結果を表示する表が含まれています。検索ボタンを使用すると、この表(この表のみ)が再レンダリングされます。検索ボタンがトリガーとして構成され、表がターゲットとして構成されています。
注意: トリガー・コンポーネントに関連付けられているすべてのイベントではなく、特定のイベントが発生したときのみ、コンポーネントを再レンダリングする場合や、コンポーネントを再レンダリングするかどうかを決定するロジックが必要な場合があります。この場合、プログラムでPPRを有効にします。詳細は、7.3項「部分ページ・レンダリングのプログラムによる有効化」を参照してください。 |
トリガー・コンポーネントで、PPRリクエストが発生したことをフレームワークに通知する必要があります。コマンド・コンポーネントでは、partialSubmit
属性をtrue
に設定することでこれを行えます。これを行うと、コマンド・コンポーネントがクリックされるたびに部分ページ・リクエストが発生します。
たとえば、ページにinputText
コンポーネント、commandButton
コンポーネントおよびoutputText
コンポーネントが含まれるとします。ユーザーがinputText
コンポーネントに値を入力してcommandButton
コンポーネントをクリックすると、入力値がoutputText
コンポーネントに反映されます。commandButton
コンポーネントのpartialSubmit
属性をtrue
に設定します。
ただし、コマンド・コンポーネント以外のコンポーネントでPPRをトリガーできます。ADF Facesの入力コンポーネントと選択コンポーネントには、値が変更されると部分ページ・リクエストを自動的にトリガーする機能があります。この機能を使用するには、入力または選択コンポーネントのautoSubmit
属性を使用して、値が入力されて送信されたときに、valueChangeEvent
イベントが発生するようにします。ターゲット・コンポーネントが設定されているかぎり、フレームワークにPPRを実行するよう通知するのはこのイベントです。前述の例で、commandButton
コンポーネントを削除し、かわりにinputText
コンポーネントのautoSubmit
属性をtrue
に設定します。値が変更されるたびに、PPRリクエストが起動されます。
ヒント: 入力コンポーネントの |
PPRがトリガーされると、ターゲットとして構成されているコンポーネントが再レンダリングされます。コンポーネントは、partialTriggers
属性をトリガー・コンポーネントの相対IDに設定することで、ターゲットとして構成します。相対IDの詳細は、3.5項「ページでのクライアント・コンポーネントの検索」を参照してください。
たとえば、inputText
コンポーネントに対する変更を受けてoutputText
を更新するには、partialTriggers
属性をinputText
コンポーネントの相対IDに設定します。
注意: コンポーネントのイベントにはデフォルトでPPRをトリガーするものがあり、たとえば、 |
注意: トリガー・コンポーネントが |
別のコンポーネントで発生したイベントに基づいてコンポーネントを再レンダリングするには、どのコンポーネントがトリガーかを宣言する必要があります。
コンポーネントで別のコンポーネントを再レンダリングする手順:
構造ウィンドウで、トリガー・コンポーネント(そのアクションによってPPRが起こるコンポーネント)を選択します。
プロパティ・インスペクタの「共通」セクションを開き、id
属性を設定します(まだ設定されていない場合)。値はそのコンポーネントのネーミング・コンテナ内で一意である必要があります。コンポーネントがネーミング・コンテナ内に含まれていない場合、IDはページで一意である必要があります。ネーミング・コンテナの詳細は、3.5項「ページでのクライアント・コンポーネントの検索」を参照してください。
ヒント: JDeveloperではコンポーネントIDが自動的に割り当てられます。この値は安全に変更できます。コンポーネントのIDは有効なXML名である必要があり、名前の先頭に数字を使用したり、IDにスペースを使用することはできません。JSFではIDでのコロン(:)も禁止されています。 |
トリガー・コンポーネントがコマンド・コンポーネントの場合、プロパティ・インスペクタで「動作」セクションを開き、partialSubmit
属性をtrue
に設定します。
トリガー・コンポーネントがフォーム内の入力または選択コンポーネントで、値を送信する場合、プロパティ・インスペクタで「動作」セクションを開き、コンポーネントのautoSubmit
属性をtrue
に設定します。
注意: コンポーネントで値を送信する場合のみ、 |
構造ウィンドウで、PPRのトリガー元イベントが発生したときに再レンダリングするターゲット・コンポーネントを選択します。
プロパティ・インスペクタで「動作」セクションを開き、partialTriggers
属性のドロップダウン・メニューをクリックして「編集」を選択します。
「属性の編集」ダイアログで、トリガー・コンポーネントを選択済パネルに移動し、「OK」をクリックします。トリガー・コンポーネントがネーミング・コンテナ内にある場合、JDeveloperで相対パスが自動的に作成されます。
ヒント:
|
例7-1に、PPRを実行するよう構成されたcommandLink
コンポーネントを示します。
例7-1 部分送信を使用して部分ページ・レンダリングを有効にするコード
<af:commandLink id="deleteFromCart" partialSubmit="true" actionListener="#{homeBean...}">
例7-2に、例7-1のIDがdeleteFromCart
のコマンド・リンクがクリックされると再レンダリングされるoutputText
コンポーネントを示します。
例7-2 他のコンポーネントによってトリガーされる部分ページ・レンダリングのコード
<af:outputText id="estimatedTotalInPopup"
partialTriggers="deleteFromCart"
value="#{shoppingCartBean...}"/>
ADF Facesアプリケーションでは、一部のコンポーネントで(暗黙的に、あるいは部分トリガーをリスニングするよう構成されていて)PPRが使用されるため、ユーザーがブラウザの戻るボタンをクリックしたときの動作は、単にJSFコンポーネントを使用するアプリケーションとは多少異なります。
単にJSFコンポーネントを使用するアプリケーションでは、ユーザーがブラウザの戻るボタンをクリックすると、最後にレンダリングされたときのDocument Object Model(DOM)の状態にページがブラウザによって戻されますが、JavaScriptの状態は、ユーザーが最初にページにアクセスしたときの状態です。
たとえば、ユーザーがPageAにアクセスしたとします。ページのコンポーネントとの対話後、JavaScriptを使用してPPRイベントが発生します。新たなバージョンのこのページをPageA1とします。次に、ユーザーがPageBに移動し、ブラウザの戻るボタンをクリックしてPageAに戻ります。ユーザーにPageA1のDOMが表示されますが、JavaScriptは実行されていないため、ページの一部はPageAのままです。つまり、ページに対する変更が失われています。ページをリフレッシュすると、JavaScriptが実行され、ユーザーはPageA1の状態に戻ります。ADF Facesを使用するアプリケーションでは、リフレッシュが不要になり、フレームワークでビルトイン・サポートが提供されるため、戻るボタンをクリックするとJavaScriptが実行されます。
多くのイベントが関連付けられているカレンダなどのコンポーネントでは、イベントがトリガーされるとPPRが発生し、そのたびにカレンダを部分トリガーとするコンポーネントが再レンダリングされます。ターゲットが特定のイベントでのみ再レンダリングされるようにする場合、またはターゲットが別のロジックに基づいて再レンダリングされるようにする場合、部分ページ・レンダリングをプログラムから有効にします。
たとえば、ADF Facesカレンダ・デモで、モデルにすでに存在しないアクティビティの期間をユーザーが変更しようとする場合は、カレンダをリフレッシュしてアクティビティなしに表示する必要があります(アクティビティの有効な期間が変更された場合は、カレンダが自動的にリフレッシュされます)。この例では、activityDurationChangeEvent
が起動されるびに、activityDurationChangeListener
メソッドによって、カレンダが部分ターゲットとして設定され、activity
オブジェクトがNULLになります。
開始する前に:
リスナー・メソッドを含むマネージドBeanを作成します。詳細は、2.6項「マネージドBeanの作成と使用」を参照してください。
PPRをプログラムによって有効にする手順:
JSFページで、ターゲット・コンポーネントを選択します。プロパティ・インスペクタで、clientComponentをtrueに設定します。
注意:
|
binding
属性を使用して、マネージドBeanがターゲット・コンポーネントのインスタンスで動作できるようにします。これは次のように行います。
プロパティ・インスペクタで、マネージドBeanでターゲット・コンポーネントに解決するEL式にBinding
を設定します。
前述の例では、Binding
を次のように設定できます。
#{myBean.cal1}
cal1
はターゲット・コンポーネントのIDになり、この場合は、calendar
コンポーネントになります。
マネージドBeanで、ターゲット・コンポーネントにgetメソッドおよびsetメソッドを作成します。例7-3に、calendar
コンポーネントでマネージドBeanのコードがどのようになるかを示します。
マネージドBeanで、再レンダリングするターゲット・コンポーネントを使用する必要のあるトリガー・コンポーネントのイベントに、リスナー・メソッドを作成します。
addPartialTarget()
メソッドを使用して、イベントがトリガーされると部分ターゲット・コンポーネントが再レンダリングされるよう、そのイベントの部分ターゲットとしてコンポーネントを追加します(そのIDを使用)。このメソッドを使用して、再レンダリングするコンポーネントと再レンダリングをトリガーするイベントを関連付けます。
例7-4に、カレンダをターゲットとして追加するActivityDurationChangeEvent
リスナーを作成する方法を示します。
例7-4 部分ターゲットを使用した再レンダリング
public void activityDurationChangeListener(CalendarActivityDurationChangeEvent ae) { CalendarActivity activity = ae.getCalendarActivity(); if (activity == null) { // no activity with that id is found in the model System.out.println("No activity with event " + ae.toString()); setCurrActivity(null); // Since the user has acted on an activity that couldn't be found, // ppr the page so that they no longer see the activity RequestContext adfContext = RequestContext.getCurrentInstance(); adfContext.addPartialTarget(getCal1()); return; } DemoCalendarActivity demoActivity = ((DemoCalendarActivity)activity); TimeZone tz = getTimeZone(); demoActivity.setEndDate(ae.getNewEndDate(), tz); setCurrActivity(new DemoCalendarActivityBean(demoActivity, tz)); }
トリガー・コンポーネントを選択し、プロパティ・インスペクタで、リフレッシュを実行するイベントのリスナーを検索し、手順3で作成したリスナー・メソッドにバインドします。
従来のページ全体の遷移のかわりに、部分ページ・レンダリング・リクエストを使用してナビゲーションがトリガーされるように、ADF Facesアプリケーションを構成できます。新しいページは、部分ページ・レンダリングを使用してクライアントに送信されます。部分ページ・ナビゲーションは、デフォルトでは無効になっています。
ブックマークやリフレッシュが行われたときなど、位置を把握しておくために、フレームワークでURLのハッシュ部分を使用します。URLのこの部分には、ブラウザに表示される実際のページが含まれます。
部分ページ・ナビゲーションは、web.xml
ファイルのoracle.adf.view.rich.pprNavigation.OPTIONS
コンテキスト・パラメータをon
に設定することで有効にできます。
部分ページ・ナビゲーションを使用する手順:
web.xml
ファイルをダブルクリックします。
ソース・エディタで、oracle.adf.view.rich.prNavigation.OPTIONS
パラメータを次のいずれかに変更します。
on
: 部分ページ・ナビゲーションを有効にします。
注意: パラメータを |
onWithForcePPR
: 部分ページ・ナビゲーションを有効にし、すべてのアクション・イベント(ナビゲーションが行われないアクション・イベントも含む)でPPRチャネルを使用するためのフレームワークを通知します。部分ページ・ナビゲーションでは、PPRチャネルを介してアクション・イベントを送信する必要があるため、このオプションを使用して部分ページ・ナビゲーションを簡単に有効化できます。
部分ページ・ナビゲーションを使用している場合、通常はページのビジュアル・コンテンツのみ再レンダリングされます(ヘッダー・コンテンツはすべてのページで一定のままです)。ただし、ページのアクションがフル・ページ送信を使用するように定義されている場合、およびアクションでナビゲーションが行われない場合も、ドキュメント全体が再レンダリングされます。
PPRナビゲーションを使用する前に、次の点に注意します。
PPRナビゲーションを使用する場合、このナビゲーションに関連するすべてのページで同じCSSスキンを使用する必要があります。
PPRナビゲーションでURLのハッシュ部分が使用されるため、ナビゲーションでのページ内のアンカーにハッシュ部分を使用できません。
標準のページ・ナビゲーションとは異なり、部分ナビゲーションではJavaScriptグローバル(グローバル・スコープに定義されている変数および関数)はアンロードされません。これが発生するのは、ウィンドウ・オブジェクトが部分ページの遷移でも残るためです。ページ固有のグローバル変数および関数を使用するアプリケーションでは、AdfPage.getPageProperty()
メソッドおよびAdfPage.setPageProperty()
メソッドを使用して、それらのオブジェクトを格納する必要があります。