コーディング概念について

学習の目的

この単元を完了すると、次のことができるようになります。
  • コントローラや要求などの基本概念を Visualforce から Aura コンポーネントに対応付ける。
  • Aura コンポーネントコードの最も発生頻度が高い構文エラーを避ける。
  • 疎結合のコンポーネントの利点と疎結合を形成する方法を説明する。

概念: コントローラ

ついに! 知っている名前の概念が出てきました。

シュート!馴染みのある名前にも関わらず、この領域では、Visualforce の専門知識が Aura コンポーネントに当てはまりません。Visualforce の主要機能の 1 つが標準コントローラです。ページに単一の属性を設定することで、そのページを sObject 型にバインドし、コードを記述せずとも多くの自動動作 (レコードデータの読み取りおよび書き込みなど) を使用できるようになります。標準コントローラを使用すれば、プログラマでない多くのユーザが、自由にカスタマイズされた Visualforce ページを作成できます。これは Aura コンポーネントでは実現できません。レコードを操作するコンポーネントを作成するにはコードの記述が必要です。

Visualforce のカスタムコントローラはどうでしょうか? 自分でコードを記述する必要があります。Aura コンポーネントコントローラとはどう違うのでしょうか?シュート!

第一に、Visualforce コントローラはサーバ側で実行され、Aura コンポーネントコントローラはクライアント側で実行されます。Lightning コンポーネントコントローラはサーバ側で実行されることもあります。Visualforce コントローラは Apex で記述されます。一方で Aura コンポーネントコントローラは JavaScript で記述されますが、Apex で記述されることもあります。

Visualforce コントローラのアーキテクチャ Aura コンポーネントコントローラのアーキテクチャ
Visualforce コントローラのアーキテクチャ Lightning コンポーネントコントローラのアーキテクチャ

この図からわかるとおり、2 つのアーキテクチャは異なります。この違い、つまりクライアント側コントローラであるということは、記述するコードに影響を与えます。Aura コンポーネントコントローラのコードはクライアント側で実行されますが、データはサーバ側に保存されます。キャッシュがない場合、新しいデータが必要になるたびに何らかのサーバ要求を行うことになります。それはおそらく、Visualforce コントローラであれば記述することがなかったコードです。さらに、リモート要求は非同期のコールバックベースのスタイルで記述されるため、既存のコントローラコードとは大きく異なる可能性があります。

また、多くのカスタム Visualforce コントローラと拡張では、StandardController または StandardSetController Apex クラスを使用して、組み込みの動作が置き換えられるのではなく、拡張されています。残念ながら、これらは Visualforce 独自のものです。Aura コンポーネントのサーバ側コントローラコードで再利用することはできません。自分で記述しなければならないコードが増えました。

梯子! ここで、よいお知らせがあります。JavaScript Remoting と Apex の @RemoteAction メソッドを使用して Visualforce ページを作成するだけで、Aura コンポーネントでの再利用度が高いコントローラコードを設計したことになります。既存のコードを更新する必要はありますが、新しいアーキテクチャへと飛躍的に近づきました。

梯子! 最後に、とてもよいお知らせです。Lightning データサービス (LDS) は、Aura コンポーネントのみで使用できます。これは、Aura コンポーネントの機能の中で、標準コントローラに最も近いものです。いくらかのコードを記述する必要はあります。通常のコントローラほどではないとは言え、事実です。ただ、LDS には非常に強力で、組み込みキャッシュや更新通知といった素晴らしい機能が含まれています。切り替えたら、もう戻れないでしょう。LDS の詳細は「リソース」セクションを参照してください。

概念: アクション

Visualforce でのアクションとは、最後に PageReference を返すコントローラメソッドです。通常、アクションはボタンやリンクに関連付けられ、ユーザがアプリケーションに求める動作を表します。アクションの後は、次のページや結果ページに移動したり「ホーム」に戻ったりします。たとえば、編集ボタンを押すと、レコードのデータを読み込むアクションメソッドがコールされて、編集フォームがあるページに移動します。

梯子!Aura コンポーネントアクションもほぼ同じです。アクションは、JavaScript で記述された関数であり、ユーザインターフェイス要素に関連付けられています。やっと梯子の出番です!

ちょっと待ってください。実は重要な違いがあります。これを見落とすと、梯子で登るどころか、シュートで滑り落ちることになってしまいます。

まずアクションは、Visualforce あるいは Aura コンポーネントの直接のメソッドでも関数コールでもありません。ユーザがコールするのではなく、適切なタイミングでフレームワークがそれらを呼び出します。ここまでは同じです。

ただし Visualforce でのアクションとは、Apex クラス上に定義されたメソッドです。メソッドの前後には、インスタンス変数やクラスメソッド、インスタンスメソッドなどの言語インフラストラクチャがあります。

シュート!Aura コンポーネントアクションはクラスでは定義されません。Lightning コンポーネントアクションは関数定義であり、名前-値ペアを含むオブジェクトリテラル表記の JavaScript オブジェクトの要素の値 (右) 側で宣言されます。次に、簡単な例を示します。
({
    myAction : function(component, event, helper) {
        // add code for the action
    },
})

この宣言スタイルの違いは、構文と構造に影響を及ぼします。構文では、関数宣言の後 (行 4) のカンマに注目してください。 アクションハンドラはカンマで区切ります。Apex では、これは構文エラーになります。オブジェクトリテラル表記では、2 つのアクション定義の間にカンマがないと構文エラーになります。カンマの欠落は見つけにくいエラーですので、アクションハンドラを区切るときには常にカンマを使用することを習慣付けてください。

ヒント

ヒント

プラグインが可能な外部エディタを使用している場合は、環境に ESLint などの JavaScript 検証ツールを追加することを検討してください。これは JavaScript 構文エラーであるため、ほぼすべての lint スタイルのツールがこのエラーを 2 行以上離れる前に検出できます。

構文に差異があることによって、コントローラコードがコントローラリソース内の他の関数や値にアクセスできなくなります。コントローラ内でのヘルパーメソッドの宣言はできませんし、インスタンスや静的プロパティの作成などもできません。一方で、再利用可能なコードを関連ヘルパー内に置き、インスタンス値をコンポーネントの属性として保存します。それについて詳しく見てみましょう。

概念: プロパティ、属性、「Expando」

Apex プロパティは、カスタムロジックを基盤とする (効果的な) インスタンス変数です。Visualforce コントローラまたは拡張で Apex プロパティを定義すると、ページ上の式でそれらを使用できます。コントローラプロパティの取得や設定には副次的影響が発生しない (コンピュータサイエンス用語では冪等と言います) ようになっていますが、プロパティはヘルパーメソッドをコールして基盤となるロジックを共有または抽象化できます。Visualforce コントローラでは、プロパティは非常に有用で一般的です。

Aura コンポーネントの JavaScript コントローラファイルでも同じようなプロパティを作成したいと思うかもしれませんが、それはできません。ヘルパーへのプロパティの追加を試してみると、うまくいくように思えるかもしれません。ただし、ヘルパーはシングルトンであり、コンポーネントのすべてのインスタンスで共有されます。これは、クラス静的変数に近いものであるため、個々のコンポーネントの状態を保存するためには使用できません。

では、どうすればよいのでしょうか?

コンポーネントの属性

コンポーネントマークアップの式内で値にアクセスする必要がある場合は、コンポーネント属性を使用します。コンポーネント属性は次のように宣言されます。
<aura:attribute name="myAttribute" type="Integer"/>
コンポーネント属性には、少なくとも名前とデータ型が必要です。(デフォルトの省略可能な属性などもあります。)マークアップで属性を参照するには、標準式構文を使用します。
{!v.myAttribute}
(式と式構文については、次のモジュールで説明します。)

コントローラ JavaScript コードで属性値を取得および設定するには get メソッドと set メソッドを使用します。get 関数と set 関数を使用してコンポーネント属性値を取得および設定します。

get メソッドと set メソッドは、myAction アクションハンドラ関数に渡される component パラメータ上で使用できる関数です。
({
    myAction : function(component, event, helper) {
        var counter = component.get("v.myAttribute");
        counter++;
        component.set("v.myAttribute", counter);
    },
})
ここでは、get (行 3) によって myAttribute コンポーネント属性の値が取得され、その値がローカルの counter 変数に割り当てられます。counter は増分され、その後 set (行 5) によってコンポーネント属性が更新されます。

コンポーネントの属性の値を他のコンポーネントが操作できないようにするには、属性を private にします。そうしない場合は、属性がコンポーネントの公開 API の一部になります。

JavaScript Expando と非公開属性

属性は、get/set を必ず使用する必要があるため、Visualforce 開発者には堅苦しく感じられることがあります。JavaScript に精通している場合は、JavaScript 独自の手法を使用して、アクション関数内からコンポーネントインスタンス上の値を設定しようとするかもしれませんね。

component._myExpando = "A new string variable";

この expando は、その場で作成され、コンポーネントインスタンスの一部になります。悪い点が見当たらない、軽量の、非公開インスタンス変数に見えます。

問題は、expando は軽微なバグやメモリーリークにつながる場合があるということです。うまく機能すると思われる一方で、問題が発生する可能性も捨てきれません。そのため、Salesorce では expando の使用はお勧めしません。お勧めする方法は、コンポーネント属性を作成し、アクセスレベルを private に設定することです。(非公開属性の名前には、プレフィックスとしてアンダースコアを使用して (_myAttribute など)、非公開属性であることを明確にするとよいでしょう)

概念: メソッドコールとイベント

このモジュールの最後に大きな概念について説明します。

Visualforce ページは (おそらく) メソッドで実行されています。式、プロパティ、アクションは、すべて関数コールに行き着きます。関数 (またはメソッド) コールは見えやすく、コントローラ Apex クラス内で宣言します。実行順序や動作の理由を追跡するのが簡単です。(とは言っても「簡単」というのは相対的な言葉ですね。ここはひとまずお付き合いください。)

また、メソッドコールは、アプリケーションの要素間の密結合を表します。ページはコントローラや拡張と密に結合され、さらにそれらが他の Apex クラスに結合されている場合もあります。要素間の関係は、追跡するのは簡単ですが、不安定であったり再利用しにくい可能性もあります。

Aura コンポーネントは、Visualforce のこれらの制限事項に対処するように設計されました。特に、コンポーネントは (意図的に) 疎結合されています。この疎結合のメカニズムがイベントです。

メソッドコールは、物理的な電線のようにコール元とコール先を接続する「固定ライン」のようなものだと考えることができます。一方の端でスイッチを入れると、もう一方でライトが点灯します。物理的な配線では、複数のデバイスを同じ回路内に置くことができますが、その場合、玄関のライトを点灯しようとすると、クローゼットのライトも点灯してしまいます。ソフトウェアでも同じことです。密結合されたシステムの要素を再利用すればするほど副次的影響が発生し、新しい要素を継ぎ合わせにくくなります。

イベントを使用して Aura コンポーネント間で通信を行うと「ワイヤレス」の接続が形成されます。スイッチを入れる (イベントを起動する) ことは無線信号のようなものです。誰か (別のコンポーネント) がその周波数で聞いていれば (そのイベントのハンドラを持っていれば)、信号を受信したときにアクションを実行することができます。ただし、孤独な無線通信士には、聞いている人がいるかどうかはわかりません。同様にコンポーネントは、イベントが受信され処理されるかどうかにかかわらず、正しく動作するように記述します。

たとえ話も苦しくなってきたところで、具体的なアドバイスを 2 つお伝えして終わりにしたいと思います。

  • コンポジションの原則と疎結合の原則を偏りなく共に理解することが、開発者としての成長につながります。この手法は Visualforce で慣れていたものとは異なります。難しく感じる人もいるでしょうが、これには学習と経験が物を言います。
  • メソッドを Visualforce と同じように扱わないようにします。Aura コンポーネントでもメソッドを公開し、コールできることにきっと気づくでしょう。設計の困難に直面したときに、慣れ親しんだ方法へと回帰したくなる気持ちはわかりますが、誘惑に打ち勝ちましょう。Aura コンポーネントメソッドには、それに見合った使い方というものがあります。目的を達するのに適切なツールとなる場合は、ぜひ使用してください。ただし「金槌を持っていると、すべてのものが釘に見える」という有名な言葉の通りにならないように、あらゆる問題をそれで解決しようとは思わないでください。
無料で学習を続けましょう!
続けるにはアカウントにサインアップしてください。
サインアップすると次のような機能が利用できるようになります。
  • 各自のキャリア目標に合わせてパーソナライズされたおすすめが表示される
  • ハンズオン Challenge やテストでスキルを練習できる
  • 進捗状況を追跡して上司と共有できる
  • メンターやキャリアチャンスと繋がることができる