Visualforce ページの実行順序の例
次の例では、ユーザが Visualforce ページを操作するときのページのライフサイクルを説明します。例に使用されるページは、取引先に関する情報 (ページの変数の値) を表示し、キー値が false 以外に設定されている場合にユーザが取引先の詳細を編集できるように設計されています。
この例で使用する Visualforce ページを設定する手順は、次のとおりです。
-
componentController というカスタムコンポーネントのコントローラを作成します。
-
editMode というカスタムコンポーネントを作成します。
-
myController というカスタムコントローラを作成します。
-
lifecycle というコントローラ拡張を作成します。
-
setEmps というページを作成します。
get 要求の例 1
1 つ目の例では、フォーム https://Salesforce_instance/apex/setEmps?id=recordId の URL を使用して、setEmps ページに移動します。Salesforce_instance はインスタンスの名前 (na1 など) で、recordID は組織の取引先レコードの ID (001D000000IRt53 など) です。次のページに似たコンテンツのページが表示されます。
ライフサイクルを追跡して、なぜページがこのように表示されるのかを確認しましょう。URL を直接入力してページを要求したため、このページは、postback 要求ではなく、get 要求により生成されています。
- get 要求では、はじめにカスタムコントローラとコントローラ拡張のコンストラクタメソッドがコールされます。myController メソッドは、コントローラのコンストラクタで、lifecycle メソッドは、拡張のコンストラクタです。これらが実行され、2 つのオブジェクトが生成されます。コントローラには account という変数があります。これは、ク���リする取引先オブジェクトを識別するために URL の id パラメータを使用するクエリによって生成されたものです。拡張には acct という変数があります。これはコントローラの getAccount メソッドをコールして作成されたものです。getAccount メソッドには副次的影響はありません。
- get 要求における次のステップではカスタムコンポーネントが作成され、関連付けられたコントローラまたはコントローラ拡張のコンストラクタメソッドが実行されます。ページには、1 つのカスタムコンポーネントが含まれます。
このカスタムコンポーネントには、コントローラが関連付けられていますが、このコントローラには明示的なコンストラクタはありません。明示的なコンストラクタがないすべての Apex オブジェクトと同様に、このオブジェクトは引数をとらない暗黙的な公開コンストラクタを使用して作成されます。カスタムコンポーネントの作成の一部として、カスタムコンポーネントの value 属性が設定されます。この場合、式 {!$CurrentPage.parameters.key} の結果と同じなります。URL に key 属性を指定しなかったため、value は null に設定されます。
- カスタムコンポーネントが作成されたら、カスタムコンポーネントのすべての assignTo 属性が実行されます。assignTo 属性は、その値を関連付けられたカスタムコンポーネントコントローラのクラス変数に割り当てる setter メソッドです。editMode カスタムコンポーネントには、assignTo メソッドがあるため、これが実行されます。assignTo メソッドは、属性の selectedValue を value 属性に設定します。value 属性は null に設定されるため、selectedValue も null に設定されます。
- get 要求における次のステップでは、<apex:page> コンポーネントの action 属性、式、および必要な getter メソッドと setter メソッドが評価されます。以下でこれらの手順を順に行いますが、これらの評価の順序は不確定であり、次に示す順序とは異なる場合があります。
- <apex:page> コンポーネントには、拡張の resetEmp メソッドをコールする action 属性があります。そのメソッドは、acct オブジェクトの numberofemployees 項目を 10 に設定します。
- ページで評価する式は複数あります。次の 3 つに絞って説明します。
-
<apex:pageBlock title="{!greeting}">
<apex:pageblock> の title 属性は、ライフサイクル拡張 getGreeting の getter メソッドをコールします。これは、「Global Media の最新情報」としてページに表示されます。
-
<apex:form rendered="{!$CurrentPage.parameters.key = 'true'}">
<apex:form> の rendered 属性は、key パラメータの値に基づいて設定されます。ページをコールするときに key を設定しなかったため、フォームは表示されません。
-
Value = {!value}<br/> selectedValue = {!selectedValue}<br/> EditMode = {!EditMode}この式は、カスタムコンポーネントに現れます。value と selectedValue は null に設定されることは前に説明しましたが、EditMode の値はまだ不明です。EditMode は、componentController の boolean 変数です。value が null であるかどうかに基づいて設定されます。
value は null であるため、EditMode は false に設定されます。ただし、EditMode の setter メソッドには副次的影響があります。editMode を設定する作業の一部として、selectedValue を value に設定しました。value は null であるため、これによる変更はありませんが、この動作によって後の例に影響が出ます。
-
<apex:pageBlock title="{!greeting}">
- 他の式とメソッドが同様に評価されます。
- <apex:form> コンポーネントは表示されないため、ビューステートは作成されません。
-
get 要求の最後のステップは、HTML をブラウザに送信して、その HTML を表示させることです。
get 要求の例 2
2 つ目の例では、フォーム https://Salesforce_instance/apex/setEmps?id=recordId&key=false の URL を使用して、setEmps ページに移動します。Salesforce_instance はインスタンスの名前 (na1 など) で、recordID は組織の取引先レコードの ID (001D000000IRt53 など) です。最初の例とは異なり、この例には key=false という 2 つ目のパラメータが含まれます。次のページに似たコンテンツのページが表示されます。
も��一度ライフサイクルを追跡しましょう。このページも、get 要求の結果生成されるページです。
- get 要求では、はじめにカスタムコントローラとコントローラ拡張のコンストラクタメソッドがコールされます。myController メソッドは、コントローラのコンストラクタで、lifecycle メソッドは、拡張のコンストラクタです。これらが実行されて、2 つのオブジェクトが生成されています。コントローラには account という変数があり、これは、クエリする取引先レコードを識別するために URL から得る id パラメータを使用するクエリによって生成されたものです。拡張には acct という変数があります。これはコントローラの getAccount メソッドをコールして作成されたものです。
- get 要求における次のステップではカスタムコンポーネントが作成され、関連付けられたコントローラまたはコントローラ拡張のコンストラクタメソッドが実行されます。ページには、1 つのカスタムコンポーネントが含まれます。
このカスタムコンポーネントにはコンストラクタのない関連コントローラがあるため、コントローラオブジェクトは、引数をとらない暗黙的な公開コンストラクタを使用して作成されます。カスタムコンポーネントの作成の一部として、カスタムコンポーネントの value 属性が設定されます。この場合、式 {!$CurrentPage.parameters.key} の結果と同じなります。key 属性を false に指定したため、value は false に設定されます。
- カスタムコンポーネントが作成されたら、カスタムコンポーネントのすべての assignTo 属性が実行されます。assignTo メソッドは、属性の selectedValue を value 属性に設定します。value 属性は false に設定されるため、selectedValue は false に設定されます。
- get 要求における次のステップでは、<apex:page> コンポーネントの action 属性、式、および必要な getter メソッドと setter メソッドが評価されます。以下でこれらの手順を順に行いますが、これらの評価の順序は不確定であり、次に示す順序とは異なる場合があります。
- <apex:page> コンポーネントには、拡張の resetEmp メソッドをコールする action 属性があります。そのメソッドは、acct オブジェクトの numberofemployees 項目を 10 に設定します。
- ページの式のうち、ここで選択した 3 つの式が評価される方法を確認しましょう。
- <apex:pageBlock title="{!greeting}">
- <apex:pageblock> の title 属性は、ライフサイクル拡張 getGreeting の getter メソッドをコールします。これは、「Global Media の最新情報」としてページに表示されます。
- <apex:form rendered="{!$CurrentPage.parameters.key = 'true'}">
- <apex:form> の rendered 属性は、key パラメータの値に基づいて設定されます。ページをコールするときに key を false に設定したため、フォームは表示されません。
- Value = {!value}<br/> selectedValue = {!selectedValue}<br/> EditMode = {!EditMode}
- この式は、カスタムコンポーネントに現れます。value が null ではないため、EditMode は true に設定されます。この時点で、selectedValue は null に設定されます。ただし、EditMode の setter メソッドには副次的影響があります。この場合、副次的影響によって、selectedValue は、カスタムコンポーネントの value 属性に設定されます。value は false に設定されているため、selectedValue は false に設定されます。このことから、メソッドで副次的影響を使用すべきでないことの理由がわかります。評価順序が異なり、EditMode の setter が評価される前に selectedValue の値が決定される場合でも、selectedValue は null になります。実行順序は保証されないため、selectedValue の結果は、このページに次回アクセスしたときに変化する可能性があります。
- <apex:form> コンポーネントは表示されないため、ビューステートは作成されません。
- get 要求の最後のステップは、HTML をブラウザに送信して、その HTML を表示させることです。
get 要求の例 3
3 つ目の例では、フォーム https://Salesforce_instance/apex/setEmps?id=recordId&key=true の URL を使用して、setEmps ページに移動します。Salesforce_instance はインスタンスの名前 (na1 など) で、recordID は組織の取引先レコードの ID (001D000000IRt53 など) です。2 つ目の例とは異なり、この例では key=true が設定されます。次のページに似たコンテンツのページが表示されます。
もう一度 get 要求のライフサイクルを追跡しましょう。
- get 要求では、はじめにカスタムコントローラとコントローラ拡張のコンストラクタメソッドがコールされます。myController メソッドは、コントローラのコンストラクタで、lifecycle メソッドは、拡張のコンストラクタです。これらが実行されて、2 つのオブジェクトが生成されています。コントローラには account という変数があり、これは、クエリする取引先レコードを識別するために URL から得る id パラメータを使用するクエリによって生成されたものです。拡張には acct という変数があります。これはコントローラの getAccount メソッドをコールして作成されたものです。
- get 要求における次のステップではカスタムコンポーネントが作成され、関連付けられたコントローラまたはコントローラ拡張のコンストラクタメソッドが実行されます。ページには、1 つのカスタムコンポーネントが含まれます。
このカスタムコンポーネントにはコンストラクタのない関連コントローラがあるため、コントローラオブジェクトは、引数をとらない暗黙的な公開コンストラクタを使用して作成されます。カスタムコンポーネントの作成の一部として、カスタムコンポーネントの value 属性が設定されます。この場合、式 {!$CurrentPage.parameters.key} の結果と同じなります。key 属性を true に指定したため、value は true に設定されます。
- カスタムコンポーネントが作成されたら、カスタムコンポーネントのすべての assignTo 属性が実行されます。assignTo メソッドは、属性の selectedValue を value 属性に設定します。value 属性は true に設定されるため、selectedValue は true に設定されます。
- get 要求における次のステップでは、<apex:page> コンポーネントの action 属性、式、および必要な getter メソッドと setter メソッドが評価されます。以下でこれらの手順を順に行いますが、これらの評価の順序は不確定であり、次に示す順序とは異なる場合があります。
- <apex:page> コンポーネントには、拡張の resetEmp メソッドをコールする action 属性があります。そのメソッドは、acct オブジェクトの numberofemployees 項目を 10 に設定します。
- ページの式のうち、ここで選択した 3 つの式が評価される方法を確認しましょう。
- <apex:pageBlock title="{!greeting}">
- <apex:pageblock> の title 属性は、ライフサイクル拡張 getGreeting の getter メソッドをコールします。これは、「Global Media の最新情報」としてページに表示されます。
- <apex:form rendered="{!$CurrentPage.parameters.key = 'true'}">
- <apex:form> の rendered 属性は、key パラメータの値に基づいて設定されます。ページをコールするときに key を true に設定したため、フォームが表示されます。
- Value = {!value}<br/> selectedValue = {!selectedValue}<br/> EditMode = {!EditMode}
- この式は、カスタムコンポーネントに現れます。value が null ではないため、EditMode は true に設定されます。以前の例と同様に、selectedValue は null に設定されます。EditMode の setter メソッドの副次的影響によって、selectedValue は true に設定されます。
- <apex:form> コンポーネントが表示されるため、ビューステートが作成されます。
- get 要求の最後のステップは、HTML をブラウザに送信して、その HTML を表示させることです。
postback 要求の例
最初の 2 つの例とは異なり、3 つ目の例では、編集可能項目のクリック可能なボタンと共に最終ページが表示されました。postback 要求がどのように機能するかを理解するために、例 3 の最終ページを使用して、取引先名を「Pan Galactic Media」、従業員数を「42」、および業種を「その他」に変更します。その後 [保存] をクリックします。これにより、postback 要求が開始されます。
- postback 要求では、はじめにビューステートが復号化されます。ビューステートには、ページを表示するために必要な情報がすべて含まれます。postback 要求中に操作が失敗した場合、ページをユーザに表示するためにビューステートが使用されます。
- 次に、すべての式が評価され、コントローラとコントローラ拡張のメソッドが実行されます。ページの式のうち、ここで選択した 3 つの式が評価される方法を確認しましょう。
- <apex:pageBlock title="{!greeting}">
- <apex:pageblock> の title 属性は、ライフサイクル拡張 getGreeting の getter メソッドをコールします。この編集では、取引先名の値を変更しました。したがって、greeting の値は、「Pan Galactic Media の最新情報」に変更されます。
- <apex:form rendered="{!$CurrentPage.parameters.key = 'true'}">
- <apex:form> の rendered 属性は、key パラメータの値に基づいて設定されます。key パラメータを変更していないため、ビューステートの値が使用されます。ビューステートが作成されたときの値は true であったため、この値は true のままであり、フォームが表示されます。
- Value = {!value}<br/> selectedValue = {!selectedValue}<br/> EditMode = {!EditMode}
- これらの値を変更していないため、各式について、ビューステートの値が使用されます。
- 最後に、postback 要求をトリガした save アクションが評価されます。save アクションは、コントローラの次のメソッドです。
このメソッドによって、レコードは新しいデータで更新されます。このメソッドが失敗する場合 (ユーザにレコードを更新する権限がない場合、または変更によってトリガされる入力規則がある場合)、エラーメッセージとそのエラーの説明と共にページが表示されます。ユーザが入力した値は失われません。これらの値は、ユーザが [保存] ボタンをクリックしたときの状態に維持されます。エラーが発生しなかった場合、オブジェクトのデータは更新され、ビューステートが更新されます。また、postback 要求をトリガしたアクションにページのリダイレクトが含まれていなかったため、ビューステートが更新されます。生成された HTML がブラウザに送信されます。
