Tune in to Trailblazers Innovate for Salesforce product news,
demos, and latest roadmaps. Register here.
close
進行状況の追跡を始めよう
Trailhead のホーム
Trailhead のホーム

カスタムコントローラの作成および使用

学習の目的

この単元を完了すると、次のことができるようになります。
  • カスタムコントローラおよびその主要な属性について説明する。
  • カスタムコントローラクラスを作成する。
  • Visualforce ページでカスタムコントローラを使用する。

カスタムコントローラの概要

カスタムコントローラには、Visualforce ページで使用できるカスタムロジックとデータ操作が含まれています。たとえば、表示項目のリストの取得、外部 Web サービスへのコールアウトの実行、データの検証と挿入などの操作をカスタムコントローラで実行でき、コントローラとして使用する Visualforce ページでこれらのすべての操作を行うことができます。

他の単元では、Web アプリケーションを作成するためにモデル–ビュー–コントローラ (MVC) 設計パターンが Visualforce でどのようにサポートされているかについて説明しました。コントローラは通常、Visualforce ページに表示するデータを取得します。また、ボタンがクリックされるなどのページアクションに応答して実行されるコードが含まれます。標準コントローラを使用する場合、プラットフォームにより多くの標準機能が提供されます。

しかし、どのような状況にも適用できるわけではなく、すべての Web アプリケーションが標準というわけでもありません。既存の機能の上書き、アプリケーションによるナビゲーションのカスタマイズ、コールアウトまたは Web サービスを使用する場合、またはページの情報にアクセスする方法についてより詳細な制御が必要な場合は、Visualforce を使用することでこのような操作が可能になります。Apex を使用してカスタムコントローラを記述し、開始から完成までのアプリケーションロジックを完全に制御できます。

カスタムコントローラを使用する Visualforce ページを作成する

<apex:page> controller 属性でコントローラクラスの名前を参照して、カスタムコントローラを Visualforce ページに追加します。

ページでカスタムコントローラを使用する場合、標準コントローラは使用できません。カスタムコントローラの設定には、異なる属性がページで使用されます。

  1. 新しい Visualforce ページを作成するには、開発者コンソールを開き、[File (ファイル)] | [New (新規)] | [Visualforce Page (Visualforce ページ)] をクリックします。ページ名に「ContactsListWithController」と入力します。
  2. エディタで、任意のマークアップを次のように置き換えます。
    <apex:page controller="ContactsListWithController">
        <apex:form>
            <apex:pageBlock title="Contacts List" id="contacts_list">
                <!-- Contacts List goes here -->
            </apex:pageBlock>
        </apex:form>
    </apex:page>
    このページを保存しようとすると、ContactsListWithController がまだ存在しないため、エラーになります。これについては、次で対処しますので問題ありません。

カスタムコントローラ Apex クラスを作成する

カスタムコントローラは、開発者コンソールを使用して自分で記述できる Apex クラスにすぎません。

カスタムコントローラロジックの記述に役立つ数多くのシステムクラスとユーティリティクラスがありますが、カスタムコントローラとして使用するクラスの唯一の要件は、それが存在するということです。

  1. 新しい Apex クラスを作成するには、開発者コンソールを開き、[File (ファイル)] | [New (新規)] | [Apex Class (Apex クラス)] をクリックします。クラス名に「ContactsListController」と入力します。
  2. エディタで、任意のコードを次のコードで置き換えます。
    public class ContactsListController {
        // Controller code goes here
    }
    Visualforce ページの場合と同様に、変更を加えた場合は変更内容を Apex に保存する必要があります。それほど大きな変更ではなく、まだ何の処理も行われませんが、Visualforce ページでのエラーがなくなります。これを確認するため、次の操作を行います。
  3. Visualforce ページに戻り、再度保存します。エラーメッセージがなくなり、ページが正常に保存されています。
  4. [Preview (プレビュー)] をクリックして、変更処理中に確認できるページのプレビューを開きます。新しいウィンドウが開き、標準の Salesforce ページヘッダーとサイドバー要素が表示されますが、コンテンツはまだありません。

作成した 2 つの新しい項目では物足りないことが一見してわかります。Visualforce ページと Apex コントローラという 2 つの項目は 90% がプレースホルダコードですが、互いにリンクされています。他のコードをコントローラに追加すると、ページでそれを使用できるようになります。

高度な操作

このカスタムコントローラクラスは、別のクラスから継承せず、Visualforce コントローラの要件を満たすインターフェースも実装しません。継承するクラスや実装するインターフェースは存在しないため、複雑なコントローラでもこのような処理は行われません。このため、Apex の使用経験を積んでいくと、独自のクラスやインターフェースを自由に作成できるようになります。

レコードを取得するメソッドを追加する

ページに表示するレコードを返す SOQL クエリを実行する getter メソッドを作成します。

ほとんどのコントローラの主な目的は、表示するデータを取得するか、データ更新を処理することです。この簡単なコントローラでは、取引先責任者レコードを検索する基本の SOQL クエリを実行し、そのレコードを Visualforce ページで使用できるようにするだけで十分です。

  1. ContactsListController クラスで、// Controller code goes here コメント行を次のコードで置き換えます。
    private String sortOrder = 'LastName';
    public List<Contact> getContacts() {
        List<Contact> results = Database.query(
            'SELECT Id, FirstName, LastName, Title, Email ' +
            'FROM Contact ' +
            'ORDER BY ' + sortOrder + ' ASC ' +
            'LIMIT 10'
        );
        return results;
    }
    このコードは、1 つの非公開メンバー変数、sortOrder という名前の文字列、1 つの公開メソッド getContacts() を追加します。sortOrder は非常にわかりやすく、単に取引先責任者の並び替え基準になる項目の名前を示します。getContacts() も単純ですが、これまでに Apex を見たことがない場合は、最初は解析しにくいこともあります。このメソッドの結果、取引先責任者レコードのリストを取得する SOQL クエリが実行され、取引先責任者のリストがメソッドのコール元に返されます。コール元になるのは、もちろん Visualforce ページです。
  2. ContactsListWithController ページで、<!-- Contacts List goes here --> コメント行を次のマークアップで置き換えます。
    <!-- Contacts List -->
    <apex:pageBlockTable value="{! contacts }" var="ct">
        <apex:column value="{! ct.FirstName }"/>
        <apex:column value="{! ct.LastName }"/>
        <apex:column value="{! ct.Title }"/>
        <apex:column value="{! ct.Email }"/>
    </apex:pageBlockTable>
    このページを保存すると、取引先責任者情報の見慣れた表が表示されます。カスタムコントローラによって返される取引先責任者リスト

ContactsListWithController ページのマークアップは、かなり見慣れたものです。<apex:page> タグの controller 属性を除き、標準コントローラを使用してページを作成する場合に使用するコードとほぼ同じです。

異なる点は、{! contacts } 式が評価されたときの処理です。このページでは、Visualforce により、その式がコントローラの getContacts() メソッドのコールに変換されます。このメソッドにより、<apex:pageBlockTable> で期待される取引先責任者レコードのリストが返されます。

getContacts() メソッドは getter メソッドと呼ばれます。その一般的なパターンでは、Visualforce マークアップの {! someExpression } により、コントローラで getSomeExpression() という名前のメソッドに自動的に接続されます。これは、表示する必要があるデータにページからアクセスする最も簡単な方法です。

新しいアクションメソッドを追加する

ページ上のユーザ入力に応答するカスタムコントローラでアクションメソッドを作成します。

Web アプリケーションでは、データの表示も重要ですが、ユーザアクションに応答することが不可欠です。カスタムコントローラでは、ユーザ活動に応答するアクションメソッドを記述することによって、ページでサポートするカスタムアクションをいくつでも作成できます。

  1. getContacts() メソッドの下にある ContactsListController クラスで、次の 2 つのメソッドを追加します。
    public void sortByLastName() {
        this.sortOrder = 'LastName';
    }
    public void sortByFirstName() {
        this.sortOrder = 'FirstName';
    }
    この 2 つのメソッドは、sortOrder 非公開変数の値を変更します。sortOrder は取引先責任者を取得する SOQL クエリで使用され、sortOrder を変更すると結果の順序が変更されます。
  2. ContactsListWithController ページで、ct.FirstName および ct.LastName の 2 つの <apex:column> タグを次のマークアップで置き換えます。
    <apex:column value="{! ct.FirstName }">
        <apex:facet name="header">
            <apex:commandLink action="{! sortByFirstName }"
                reRender="contacts_list">First Name
            </apex:commandLink>
        </apex:facet>
    </apex:column>
    <apex:column value="{! ct.LastName }">
        <apex:facet name="header">
            <apex:commandLink action="{! sortByLastName }"
                reRender="contacts_list">Last Name
            </apex:commandLink>
        </apex:facet>
    </apex:column>
    視覚的な外観に変化はありませんが、[名] および [姓] 列ヘッダーをクリックすると、取引先責任者リストの並び替え順が変更されるようになりました。すばらしいですね。

新しいマークアップにより、ネストされた 2 つのコンポーネントが各 <apex:column> コンポーネントに追加されます。<apex:column> 自体はプレーンテキストヘッダーですが、ヘッダーをクリック可能にしてみます。<apex:facet> を使用すると、列ヘッダーの内容を自由に設定できます。ここでは、正しいアクションメソッドをコールするリンクにしてみます。リンクの作成には <apex:commandLink> コンポーネントを使用し、コントローラでアクションメソッドを参照する式に action 属性を設定します。(getter メソッドとは異なり、アクションメソッドは、それらを参照する式と同じように指定されます)。

リンクをクリックすると、コントローラでアクションメソッドが起動します。アクションメソッドにより並び替え順の非公開変数が変更され、表が再表示されます。表が再表示されると、{! contacts } が再評価され、直前に設定された並び替え順でクエリが返されます。最終結果の表は、ユーザクリックによって要求された順序で再度並び替えられます。

高度な操作

このマークアップでは、[名] および [姓] 列のヘッダーテキストがハードコードされています。英語を使用しないユーザがいる場合はどうなるでしょうか。標準の Salesforce ユーザインターフェースには、すべての標準オブジェクトの項目名の翻訳バージョンがあり、カスタムオブジェクトには独自の翻訳を指定できます。これらにアクセスするには、プレーンテキストの代わりに <apex:outputText value="{! $ObjectType.Contact.Fields.FirstName.Label }"/> というマークアップを使用してください。項目名が変更されると自動的に更新されるため、組織のすべてのユーザが同じ言語を使用している場合でも、この方法は項目の表示ラベルを参照する方法として適切です。

もうひとこと...

カスタムコントローラと Apex 言語では、Visualforce ページで考えられるほぼすべてのことを実行できます。

getter メソッドは、コントローラのデータをページに渡します。対応する setter メソッドでは、ページの値をコントローラに戻すことができます。getter メソッド同様、setter には「set」プリフィックスを使用します。それ以外はこれらは単に引数を取るメソッドです。

getter と setter の代わりに、Apex のプロパティを使用できます。プロパティは、getter および setter メソッドを含む変数と、それらのメソッドをより明確にグループ化する構文との組み合わせです。カスタムオブジェクトを参照する単一プロパティは、次のように宣言できます。
public MyObject__c myVariable { get; set; }

プロパティは、公開または非公開にすることができ、get または set を省略することで読み取り専用か書き込み専用にできます。さらに、単なる値の保存および取得に加えて追加ロジックを実行する場合、get または set メソッドの実装を作成できます。

プロパティは Apex の一般機能で、Visualforce に固有のものではありません。Apex は完全なプログラミング言語で、複雑な Visualforce ページの作成に使用できるだけでなく、その他の多くの Lightning Platform 開発コンテキストでも使用されます。Apex をフル活用するさまざまな方法についての詳細は、他の場所にある Apex トピック、およびこのページの最後にあるリソースを参照してください。

Visualforce 要求および応答のライフサイクルは、最初は複雑に思えるかもしれません。特に、getter または setter (または使用している場合はプロパティ) のコールに特定の順序はないため、実行順序の連動関係は使用しないことを理解することが重要です。『Visualforce 開発者ガイド』の関連セクション、特に「カスタムコントローラおよびコントローラ拡張」の章に多数の詳細情報があります。