Skip to main content

カスタムコントローラーの作成と使用

学習の目的

この単元を完了すると、次のことができるようになります。

  • カスタムコントローラーとその主な属性について説明する。
  • カスタムコントローラークラスを作成する。
  • Visualforce ページでカスタムコントローラーを使用する。
メモ

メモ

日本語で受講されている方へChallenge は日本語の Trailhead Playground で開始し、日本との値をコピーして貼り付けます。日本語の組織で Challenge が不合格だった場合は、(1) この手順に従って [Locale (地域)] を [United States (米国)] に切り替え、(2) [Language (言語)] を [English (英語)] に切り替えてから、(3) [Check Challenge (Challenge を確認)] ボタンをクリックしてみることをお勧めします。

翻訳版 Trailhead を活用する方法の詳細は、自分の言語の Trailhead バッジを参照してください。

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

<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 クラス)] をクリックします。クラス名に ContactsListWithController と入力します。

エディターで、任意のコードを次のコードで置き換えます。

public class ContactsListWithController {
// Controller code goes here
}

Visualforce ページの場合と同様に、変更を加えた場合は変更内容を Apex に保存する必要があります。それほど大きな変更ではなく、まだ何の処理も行われませんが、Visualforce ページでのエラーがなくなります。

  1. Visualforce ページに戻り、再度保存します。エラーメッセージがなくなり、ページが正常に保存されています。
  2. [Preview (プレビュー)] をクリックして、変更処理中に確認できるページのプレビューを開きます。新しいウィンドウが開き、標準の Salesforce ページヘッダーとサイドバー要素が表示されますが、コンテンツはまだありません。

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

高度な操作

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

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

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

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

  1. ContactsListWithController クラスで、// 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() メソッドの下にある ContactsListWithController クラスで、次の 2 つのメソッドを追加します。
    public void sortByLastName() {
        this.sortOrder = 'LastName';
    }
    public void sortByFirstName() {
        this.sortOrder = 'FirstName';
    }
    この 2 つのメソッドは、sortOrder 非公開変数の値を変更します。sortOrder は取引先責任者を取得する SOQL クエリで使用され、sortOrder を変更すると結果の順序が変更されます。
  2. ContactsListWithController ページで、ct.FirstNamect.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 開発者ガイド』の関連セクション、特に「カスタムコントローラーとコントローラー拡張」の章に多数の詳細情報があります。

リソース

Salesforce ヘルプで Trailhead のフィードバックを共有してください。

Trailhead についての感想をお聞かせください。[Salesforce ヘルプ] サイトから新しいフィードバックフォームにいつでもアクセスできるようになりました。

詳細はこちら フィードバックの共有に進む