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

コントローラメソッド

Visualforce マークアップは、次の種別のコントローラ拡張とカスタムコントローラメソッドを使用できます。
  • action
  • getter
  • setter

action メソッド

action メソッドは、ユーザがボタンをクリックしたり、ページ内のある領域にマウスポインタを移動したりするなどのページイベントが発生すると、ロジックまたはナビゲーションを実行します。次のいずれかのタグの action パラメータに {! } 表記を使用することによって、ページマークアップから action メソッドをコールできます。
  • <apex:commandButton> はアクションをコールするボタンを作成する
  • <apex:commandLink> はアクションをコールするリンクを作成する
  • <apex:actionPoller> は定期的にアクションをコールする
  • <apex:actionSupport> は、別の名前つきのコンポーネントにイベント (「onclick」、「onmouseover」など) を作成し、アクションをコールする
  • <apex:actionFunction> は、アクションをコールする新しい JavaScript 関数を定義する
  • <apex:page> はページが読み込まれると、アクションをコールする

たとえば、カスタムコントローラの作成のサンプルページでは、<apex:commandButton> タグの action パラメータによって、コントローラの save メソッドがコールされます。その他の action メソッドの例は、action メソッドの定義を参照してください。

getter メソッド

getter メソッドはコントローラの値を返します。コントローラによって計算され、ページに表示される各値には、boolean 変数など、対応する getter メソッドが含まれる必要があります。たとえば、カスタムコントローラの作成のサンプルページでは、コントローラに getAccount メソッドが含まれます。このメソッドによって、ページのマークアップは、{! } 表記のあるコントローラクラスの account メンバー変数を参照することができます。<apex:inputField> タグの value パラメータは、この表記を使用して取引先にアクセスし、ドット表記を使用して取引先の名前を表示します。getter メソッドの名前は、getVariable にする必要があります。

getter メソッドを羃等にする、つまり副次的影響がないようにすることがベストプラクティスです。たとえば、変数の増分、ログメッセージの書き込み、データベースへの新規レコードの追加を行わないようにします。Visualforce では、要求の処理の過程でコールされる可能性のある getter メソッドのコール順序および回数を定義しません。1 つのページ要求での getter メソッドのコール回数に関係なく、同じ結果を生成するように getter メソッドをデザインしてください。

重要

setter メソッド

setter メソッドは、ユーザ指定の値をページマークアップからコントローラに渡します。コントローラの setter メソッドは、どの action メソッドよりも先に自動的に実行されます。

たとえば、次のマークアップは、リードの基本的な検索機能を実装するページを表示します。関連付けられているコントローラには、検索ボックスの入力に使用する getter メソッドと setter メソッドが含まれており、ユーザが [Go!] をクリックすると、検索テキストを使用して、SOSL クエリを発行します。マークアップは、検索テキストの setter メソッドを明示的にはコールしませんが、ユーザがコマンドボタンをクリックすると、doSearch action メソッドの前に setter メソッドが実行されます。

1swfobject.registerObject("clippy.codeblock-0", "9");
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17<apex:page controller="theController">
18   <apex:form>
19      <apex:pageBlock mode="edit" id="block">
20         <apex:pageBlockSection>
21            <apex:pageBlockSectionItem>
22               <apex:outputLabel for="searchText">Search Text</apex:outputLabel>
23               <apex:panelGroup>
24                  <apex:inputText id="searchText" value="{!searchText}"/>
25                  <apex:commandButton value="Go!" action="{!doSearch}" 
26                                      rerender="block" status="status"/>
27               </apex:panelGroup>
28            </apex:pageBlockSectionItem>
29        </apex:pageBlockSection>
30        <apex:actionStatus id="status" startText="requesting..."/>
31        <apex:pageBlockSection title="Results" id="results" columns="1">
32           <apex:pageBlockTable value="{!results}" var="l" 
33                               rendered="{!NOT(ISNULL(results))}">
34              <apex:column value="{!l.name}"/>
35              <apex:column value="{!l.email}"/>
36              <apex:column value="{!l.phone}"/>
37           </apex:pageBlockTable>
38        </apex:pageBlockSection>
39      </apex:pageBlock>
40   </apex:form>
41</apex:page>

次のクラスは、上記のページマークアップに使用するコントローラです。

1swfobject.registerObject("clippy.codeblock-1", "9");
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17public class theController {
18
19    String searchText;
20    List<Lead> results;
21
22    public String getSearchText() {
23        return searchText;
24    }
25
26    public void setSearchText(String s) {
27        searchText = s;
28    }
29
30    public List<Lead> getResults() {
31        return results;
32    }
33
34    public PageReference doSearch() {
35        results = (List<Lead>)[FIND :searchText RETURNING Lead(Name, Email, Phone)][0];
36        return null;
37    }
38}

getter メソッドは、コントローラから値にアクセスする場合に必ず必要なメソッドですが、値をコントローラに渡す場合、必ずしも setter メソッドを含める必要はありません。Visualforce コンポーネントが、コントローラに保存されている sObject にバインドされている場合、sObject が対応する action メソッドによって保存または更新されるかぎり、sObject 項目はユーザによって変更されると自動的に設定されます。この動作の例は、カスタムコントローラの作成のサンプルページにあります。

setter メソッドの名前は、setVariable にする必要があります。

setter メソッドを羃等にする、つまり副次的影響がないようにすることがベストプラクティスです。たとえば、変数の増分、ログメッセージの書き込み、データベースへの新規レコードの追加を行わないようにします。Visualforce では、要求の処理の過程でコールされる可能性のある setter メソッドのコール順序および回数を定義しません。1 つのページリクエストでの setter メソッドのコール回数に関係なく、同じ結果を生成するように setter メソッドをデザインしてください。

重要

カスタム拡張またはコントローラを使用したデータの取得と設定

Apex メソッドと変数がコントローラ拡張またはカスタムコントローラによって処理される順序は保証されません。このため、コントローラと拡張クラスは、実行している別のメソッドに依存するのではなく、直接そのメソッドをコールする必要があります。これは、変数の設定とデータベースのデータへのアクセスに特に当てはまります。

たとえば、次のカスタムコントローラの最初のメソッド getContactMethod1 は、contact 変数 c がすでに存在することを前提としていないため、正しい値を常に返します。一方、2 つ目のメソッド getContactMethod2 は、正しい値を返すこともありますが、c がまだ設定されていない場合は正しい値を返すとは限りません。

1swfobject.registerObject("clippy.codeblock-2", "9");
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17public class conVsBad {
18    Contact c;
19
20    public Contact getContactMethod1() {
21        if (c == null) c = [SELECT Id, Name FROM Contact LIMIT 1];
22        return c;
23    }
24
25    public Contact getContactMethod2() {
26        return c;
27    }
28}

次のカスタムコントローラにはまったく同じメソッドがあります。ただし、getContactMethod2contactMethod1 をコールするため、変数 c は常に設定され、返されるときには正しい値が常に含まれます。

1swfobject.registerObject("clippy.codeblock-3", "9");
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17public class conVsGood {
18    Contact c;
19
20    public Contact getContactMethod1() {
21        if(c == null) c = [SELECT Id, Name FROM Contact LIMIT 1];
22        return c;
23    }
24
25    public Contact getContactMethod2() {
26        return getContactMethod1();
27    }
28}

次のマークアップでは、これらのコントローラをコールする 2 つのページを示します。Visualforce マークアップは同じものであり、コントローラの名前のみが変更されています。

1swfobject.registerObject("clippy.codeblock-4", "9");
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17<apex:page controller="conVsGood">
18    getContactMethod2(): {!contactMethod2.name}<br/>
19    getContactMethod1(): {!contactMethod1.name}
20</apex:page>
1swfobject.registerObject("clippy.codeblock-5", "9");
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17<apex:page controller="conVsBad">
18    getContactMethod2(): {!contactMethod2.name}<br/>
19    getContactMethod1(): {!contactMethod1.name}
20</apex:page>