Skip to main content

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

学習の目的

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

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

メモ

このバッジのハンズオン Challenge は日本語、スペイン語 (LATAM)、ポルトガル語 (ブラジル) に対応しています。Playground の言語を変更するには、こちらの指示に従ってください。日本語等、翻訳された言語と英語に差異がある可能性があります。英語以外の言語での指示に従って Challenge に合格できなかった場合は、[言語] と [地域] をそれぞれ [English]、[アメリカ合衆国] に切り替えてからもう一度お試しください。

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

カスタムコントローラーには、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 クラス)] をクリックします。クラス名に ContactsListWithController と入力します。
  2. エディターで、任意のコードを次のコードで置き換えます。
    public class ContactsListWithController {
    // Controller code goes here
    }
    Visualforce ページの場合と同様に、変更を加えた場合は変更内容を Apex に保存する必要があります。それほど大きな変更ではなく、まだ何の処理も行われませんが、Visualforce ページでのエラーがなくなります。これを確認するため、次の操作を行います。
  3. Visualforce ページに戻り、再度保存します。エラーメッセージがなくなり、ページが正常に保存されています。
  4. [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 開発者ガイド』の関連セクション、特に「カスタムコントローラーとコントローラー拡張」の章に多数の詳細情報があります。

リソース

無料で学習を続けましょう!
続けるにはアカウントにサインアップしてください。
サインアップすると次のような機能が利用できるようになります。
  • 各自のキャリア目標に合わせてパーソナライズされたおすすめが表示される
  • ハンズオン Challenge やテストでスキルを練習できる
  • 進捗状況を追跡して上司と共有できる
  • メンターやキャリアチャンスと繋がることができる