この文章は Salesforce 機械翻訳システムを使用して翻訳されました。詳細はこちらをご参照ください。
英語に切り替える

Visualforce ページの実行順序の例

次の例では、ユーザが Visualforce ページを操作するときのページのライフサイクルを説明します。例に使用されるページは、取引先に関する情報 (ページの変数の値) を表示し、キー値が false 以外に設定されている場合にユーザが取引先の詳細を編集できるように設計されています。

この例で使用する Visualforce ページを設定する手順は、次のとおりです。

  1. componentController というカスタムコンポーネントのコントローラを作成します。
    1public class componentController {
    2    public String selectedValue {
    3        get;
    4        set {
    5            editMode = (value != null);
    6            // Side effect here - don't do this!
    7            selectedValue = value;
    8        }
    9    }
    10    public Boolean editMode {get; private set;}
    11}
  2. editMode というカスタムコンポーネントを作成します。
    1<apex:component controller="componentController">
    2    <apex:attribute name="value" type="String" description="Sample component."
    3        assignTo="{!selectedValue}"/>
    4    <p>
    5    Value = {!value}<br/>
    6    selectedValue = {!selectedValue}<br/>
    7    EditMode = {!EditMode}
    8    </p>
    9</apex:component>
  3. myController というカスタムコントローラを作成します。
    1public with sharing class myController {
    2
    3    private final Account account;
    4
    5      public myController() {
    6            account = [select id, name, site, NumberOfEmployees, Industry from Account 
    7                       where id = :ApexPages.currentPage().getParameters().get('id')];
    8      }
    9
    10      public Account getAccount() {
    11            return account;
    12      }
    13
    14      public PageReference save() {
    15            update account;
    16            return null;
    17      }
    18
    19      public PageReference cancel() {
    20            return null;
    21      }
    22}
  4. lifecycle というコントローラ拡張を作成します。
    1public with sharing class lifecycle {
    2
    3    private final Account acct;
    4    Integer EmpAdd;
    5
    6    public lifecycle(myController controller) {
    7        this.acct = (Account)controller.getAccount();
    8    }
    9
    10    public String getGreeting() {
    11        return acct.name + ' Current Information';
    12    }
    13    
    14    public void resetEmp() {
    15        acct.numberofemployees = 10;
    16        update acct;
    17    }
    18}
  5. setEmps というページを作成します。
    1<apex:page controller="myController" tabStyle="Account" extensions="lifecycle" action="{!resetEmp}">
    2    <apex:messages />
    3    <apex:pageBlock title="{!greeting}">
    4        <apex:outputLabel value="{!$ObjectType.account.fields.Name.label}: " 
    5                          for="acctName"/>
    6        <apex:outputField value="{!account.name}" id="acctName"/>
    7        <br/>
    8        <apex:outputLabel 
    9              value="{!$ObjectType.account.fields.NumberOfEmployees.label}: "
    10              for="emps"/>
    11        <apex:outputField value="{!account.NumberOfEmployees}" id="emps"/>
    12        <br/>
    13    </apex:pageBlock>
    14    <apex:pageBlock title="Variable values">
    15        <c:editMode value="{!$CurrentPage.parameters.key}"/>
    16    </apex:pageBlock>
    17    <apex:form rendered="{!$CurrentPage.parameters.key = 'true'}">
    18        <apex:pageBlock title="Update the Account" id="thePageBlock">
    19            <apex:pageBlockSection columns="1">
    20                <apex:inputField id="aName" value="{!account.name}"/>
    21                <apex:inputField value="{!account.NumberOfEmployees}"/>
    22                <apex:pageBlockSectionItem>
    23                    <apex:outputLabel value="{!$ObjectType.account.fields.Industry.label}"
    24                        for="acctIndustry"/>
    25                    <apex:actionRegion>
    26                        <apex:inputField value="{!account.Industry}" id="acctIndustry">
    27                            <apex:actionSupport event="onchange" rerender="thePageBlock"
    28                                status="status"/>
    29                        </apex:inputField>
    30                    </apex:actionRegion>
    31                </apex:pageBlockSectionItem>
    32            </apex:pageBlockSection>
    33            <apex:pageBlockButtons location="bottom">
    34                <apex:commandButton action="{!save}" value="Save"/>
    35                <apex:commandButton action="{!cancel}" value="Cancel" immediate="true"/>
    36            </apex:pageBlockButtons>
    37        </apex:pageBlock>
    38    </apex:form>
    39</apex:page>

get 要求の例 1

1 つ目の例では、https://Salesforce_instance/apex/setEmps?id=recordId という形式の URL を使用して、setEmps ページに移動します。Salesforce_instance はインスタンスの名前 (na1 など) で、recordID は組織の取引先レコードの ID (001D000000IRt53 など) です。次のページに似たコンテンツのページが表示されます。「Global Media の最新情報」と「変数の値」を表示するページ。get 要求の結果、生成されるページです。

ライフサイクルを追跡して、なぜページがこのように表示されるのかを確認しましょう。URL を直接入力してページを要求したため、このページは、postback 要求ではなく、get 要求により生成されています。

  1. get 要求では、はじめにカスタムコントローラとコントローラ拡張のコンストラクタメソッドがコールされます。myController メソッドは、コントローラのコンストラクタで、lifecycle メソッドは、拡張のコンストラクタです。これらが実行され、2 つのオブジェクトが生成されます。コントローラには account という変数があります。これは、照会する取引先オブジェクトを識別するために URL の id パラメータを使用するクエリによって生成されたものです。拡張には acct という変数があります。これはコントローラの getAccount メソッドをコールして作成されたものです。getAccount メソッドには副次的影響はありません。
  2. get 要求における次のステップではカスタムコンポーネントが作成され、関連付けられたコントローラまたはコントローラ拡張のコンストラクタメソッドが実行されます。ページには、1 つのカスタムコンポーネントが含まれます。
    1<c:editMode value="{!$CurrentPage.parameters.key}"/>

    このカスタムコンポーネントには、コントローラが関連付けられていますが、このコントローラには明示的なコンストラクタはありません。明示的なコンストラクタがないすべての Apex オブジェクトと同様に、このオブジェクトは引数をとらない暗黙的な公開コンストラクタを使用して作成されます。カスタムコンポーネントの作成の一部として、カスタムコンポーネントの value 属性が設定されます。この場合、式 {!$CurrentPage.parameters.key} の結果と同じなります。URL に key 属性を指定しなかったため、value は null に設定されます。

  3. カスタムコンポーネントが作成されたら、カスタムコンポーネントのすべての assignTo 属性が実行されます。assignTo 属性は、その値を関連付けられたカスタムコンポーネントコントローラのクラス変数に割り当てる setter メソッドです。editMode カスタムコンポーネントには、assignTo メソッドがあるため、これが実行されます。assignTo メソッドは、属性の selectedValuevalue 属性に設定します。value 属性は null に設定されるため、selectedValue も null に設定されます。
  4. 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}
        この式は、カスタムコンポーネントに現れます。valueselectedValue は null に設定されることは前に説明しましたが、EditMode の値はまだ不明です。EditMode は、componentController の boolean 変数です。value が null であるかどうかに基づいて設定されます。
        1set {
        2            selectedValue = value;
        3            // Side effect here - don't do this!
        4            editMode = (value != null);
        5}

        value は null であるため、EditModefalse に設定されます。ただし、EditMode の setter メソッドには副次的影響があります。editMode を設定する作業の一部として、selectedValuevalue に設定しました。value は null であるため、これによる変更はありませんが、この動作によって後の例に影響が出ます。

    • 他の式とメソッドが同様に評価されます。
  5. <apex:form> コンポーネントは表示されないため、ビューステートは作成されません。
  6. 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 つ目のパラメータが含まれます。次のページに似たコンテンツのページが表示されます。パラメータ「value=false」など、get 要求の結果として表示されるページ。

もう一度ライフサイクルを追跡しましょう。このページも、get 要求の結果生成されるページです。

  1. get 要求では、はじめにカスタムコントローラとコントローラ拡張のコンストラクタメソッドがコールされます。myController メソッドは、コントローラのコンストラクタで、lifecycle メソッドは、拡張のコンストラクタです。これらが実行されて、2 つのオブジェクトが生成されています。コントローラには account という変数があり、これ��、照会する取引先レコードを識別するために URL から得��� id パラメータを使用するクエリによって生成されたものです。拡張には acct という変数があります。これはコントローラの getAccount メソッドをコールして作成されたものです。
  2. get 要求における次のステップではカスタムコンポーネントが作成され、関連付けられたコントローラまたはコントローラ拡張のコンストラクタメソッドが実行されます。ページには、1 つのカスタムコンポーネントが含まれます。
    1<c:editMode value="{!$CurrentPage.parameters.key}"/>

    このカスタムコンポーネントにはコンストラクタのない関連コントローラがあるため、コントローラオブジェクトは、引数をとらない暗黙的な公開コンストラクタを使用して作成されます。カスタムコンポーネントの作成の一部として、カスタムコンポーネントの value 属性が設定されます。この場合、式 {!$CurrentPage.parameters.key} の結果と同じなります。key 属性を false に指定したため、value は false に設定されます。

  3. カスタムコンポーネントが作成されたら、カスタムコンポーネントのすべての assignTo 属性が実行されます。assignTo メソッドは、属性の selectedValuevalue 属性に設定します。value 属性は false に設定されるため、selectedValue は false に設定されます。
  4. 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 パラメータの値に基づいて設定されます。ページをコールするときに keyfalse に設定したため、フォームは表示されません。
      Value = {!value}<br/> selectedValue = {!selectedValue}<br/> EditMode = {!EditMode}
      この式は、カスタムコンポーネントに現れます。value が null ではないため、EditModetrue に設定されます。この時点で、selectedValue は null に設定されます。ただし、EditMode の setter メソッドには副次的影響があります。この場合、副次的影響によって、selectedValue は、カスタムコンポーネントの value 属性に設定されます。valuefalse に設定されているため、selectedValue は false に設定されます。このことから、メソッドで副次的影響を使用すべきでないことの理由がわかります。評価順序が異なり、EditMode の setter が評価される前に selectedValue の値が決定される場合でも、selectedValue は null になります。実行順序は保証されないため、selectedValue の結果は、このページに次回アクセスしたときに変化する可能性があります。

      getter または setter に副次的影響を使用しないでください。

      警告

  5. <apex:form> コンポーネントは表示されないため、ビューステートは作成されません。
  6. 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 要求の結果として表示されるページ。ページには「取引先を更新」という追加セクションが表示され、key パラメータは「true」に設定されます。

もう一度 get 要求のライフサイクルを追跡しましょう。

  1. get 要求では、はじめにカスタムコントローラとコントローラ拡張のコンストラクタメソッドがコールされます。myController メソッドは、コントローラのコンストラクタで、lifecycle メソッドは、拡張のコンストラクタです。これらが実行されて、2 つのオブジェクトが生成されています。コントローラには account という変数があり、これは、照会する取引先レコードを識別するために URL から得る id パラメータを使用するクエリによって生成されたものです。拡張には acct という変数があります。これはコントローラの getAccount メソッドをコールして作成されたものです。
  2. get 要求における次のステップではカスタムコンポーネントが作成され、関連付けられたコントローラまたはコントローラ拡張のコンストラクタメソッドが実行されます。ページには、1 つのカスタムコンポーネントが含まれます。
    1<c:editMode value="{!$CurrentPage.parameters.key}"/>

    このカスタムコンポーネントにはコンストラクタのない関連コントローラがあるため、コントローラオブジェクトは、引数をとらない暗黙的な公開コンストラクタを使用して作成されます。カスタムコンポーネントの作成の一部として、カスタムコンポーネントの value 属性が設定されます。この場合、式 {!$CurrentPage.parameters.key} の結果と同じなります。key 属性を true に指定したため、value は true に設定されます。

  3. カスタムコンポーネントが作成されたら、カスタムコンポーネントのすべての assignTo 属性が実行されます。assignTo メソッドは、属性の selectedValuevalue 属性に設定します。value 属性は true に設定されるため、selectedValue は true に設定されます。
  4. 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 パラメータの値に基づいて設定されます。ページをコールするときに keytrue に設定したため、フォームが表示されます。
      Value = {!value}<br/> selectedValue = {!selectedValue}<br/> EditMode = {!EditMode}
      この式は、カスタムコンポーネントに現れます。value が null ではないため、EditModetrue に設定されます。以前の例と同様に、selectedValue は null に設定されます。EditMode の setter メソッドの副次的影響によって、selectedValuetrue に設定されます。
  5. <apex:form> コンポーネントが表示されるため、ビューステートが作成されます。
  6. get 要求の最後のステップは、HTML をブラウザに送信して、その HTML を表示させることです。

postback 要求の例

最初の 2 つの例とは異なり、3 つ目の例では、編集可能項目のクリック可能なボタンと共に最終ページが表示されました。postback 要求がどのように機能するかを理解するために、例 3 の最終ページを使用して、取引先名を「Pan Galactic Media」、従業員数を「42」、および業種を「その他」に変更します。続いて、[保存] をクリックします。これにより、postback 要求が開始されます。

  1. postback 要求では、はじめにビューステートが復号化されます。ビューステートには、ページを表示するために必要な情報がすべて含まれます。postback 要求中に操作が失敗した場合、ページをユーザに表示するためにビューステートが使用されます。
  2. 次に、すべての式が評価され、コントローラとコントローラ拡張のメソッドが実行されます。
    ページの式のうち、ここで選択した 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}
    これらの値を変更していないため、各式について、ビューステートの値が使用されます。
  3. 最後に、postback 要求をトリガした save アクションが評価されます。save アクションは、コントローラの次のメソッドです。
    1public PageReference save() {
    2    update account;
    3    return null;
    4}

    このメソッドによって、レコードは新しいデータで更新されます。このメソッドが失敗する場合 (ユーザにレコードを更新する権限がない場合、または変更によってトリガされる入力規則がある場合)、エラーメッセージとそのエラーの説明と共にページが表示されます。ユーザが入力した値は失われません。これらの値は、ユーザが [保存] ボタンをクリックしたときの状態に維持されます。エラーが発生しなかった場合、オブジェクトのデータは更新され、ビューステートが更新されます。また、postback 要求をトリガしたアクションにページのリダイレクトが含まれていなかったため、ビューステートが更新されます。生成された HTML がブラウザに送信されます。postback 要求の結果として表示されるページ