Angularでよく耳にする「ディレクティブ」という概念は、一言でいうと「HTML要素に特別な振る舞いや制御を付与するための拡張機能」です。
このページでは、そもそもディレクティブって何?という人向けにディレクティブのイメージ・本質的な理解が進むように1からわかりやすく使い方や注意点を解説していきます。
まずはディレクティブのイメージをつかむ
たとえば、普通のHTMLでは<div>
や<p>
などの要素をただ書いただけでは、そこに特別な「動き」はありません。テキストを表示したり、見出しを表現したりするだけです。
そこに「この要素は、ある条件が満たされたら表示し、そうでなければ非表示にしたい」とか、「ある配列のデータをもとに、同じ形の要素を繰り返し表示したい」といった動的な振る舞いを付けたくなる場面が出てきます。
Angularにおいては、この「動的な振る舞い」をHTML要素に追加するための仕組みこそがディレクティブです。ディレクティブを使うと、HTMLタグをただ書くだけでなく、「この要素はどう表示されるのか」「いつレンダリングされるのか」といった命令を付け加えることができます。
「HTMLに命令を埋め込む」という発想
ディレクティブはHTML側に命令を埋め込むようなイメージで考えると理解しやすくなります。「ここにもしデータがあったら繰り返し表示する」「ここの条件がtrueなら、このブロックを描画する」といった振る舞いを、HTMLタグの属性として書けるのです。
- 例:
*ngIf="isVisible"
isVisible
という変数がtrue
のときだけ要素が表示される
- 例:
*ngFor="let item of items"
items
配列をひとつずつ取り出して要素を繰り返し生成する
こうしたディレクティブをHTMLに貼り付けるだけで、Angularはテンプレートを解釈し、内部的にDOMを追加/削除したり、表示/非表示の切り替えを行ってくれます。
コンポーネントとの違いをざっくり知る
Angularを学び始めると、ディレクティブとほぼ同時に「コンポーネント」という言葉を耳にするはずです。コンポーネントも広い意味では「ディレクティブの一種」とされますが、次のような違いがあります。
- コンポーネント
- HTMLテンプレート、TypeScriptのクラス、CSSスタイルなどをひとまとめにした「画面の部品」
<app-○○>
のような独自タグとして使うことが多い
- ディレクティブ(構造・属性ディレクティブなど)
- 画面の見た目そのものではなく、既存のHTML要素の振る舞いだけを拡張する命令書のようなイメージ
*ngIf
や*ngFor
のような構造ディレクティブ、[ngClass]
のような属性ディレクティブが代表例
このようにコンポーネントとディレクティブは、どちらも「AngularがHTMLをどう解釈して動的に扱うか」を制御していますが、コンポーネントは「見た目のかたまり」を構成するのに対し、ディレクティブは「特定の振る舞いを要素に追加する」という役割に特化しているというイメージを持つと、両者を使い分けやすくなります。
ディレクティブがもたらすメリット
- HTMLテンプレートに直接“動き”を宣言できる
*ngIf
や*ngFor
を見れば、一目で「ここの要素が条件付き表示/繰り返し表示なんだ」と理解できる。
- コードの可読性・メンテナンス性の向上
- 画面遷移や表示切り替えといったロジックを、HTML側と直接リンクさせて書けるため、可読性が上がる。
- 複雑なDOM操作の削減
- もしディレクティブがなければ、JavaScriptでDOM操作のAPIを使って要素の追加削除を毎回行う必要があるが、その分の処理をAngular側が肩代わりしてくれる。
こうしたメリットから、AngularのディレクティブはアプリケーションのUIをより動的かつ宣言的に構築できる重要な機能だと言えます。
このようにディレクティブの本質は「HTML要素をベースに、より複雑な処理を記述できる拡張機能」として存在していることにあります。単純なHTMLの延長線として考えられるので、初心者の方でも慣れてくると「ここで*ngIf
を使えばいいのか」「繰り返し表示には*ngFor
を使うんだな」と自然に使いこなせるようになるでしょう。
ディレクティブの種類
Angularでは、多彩な動きをHTML要素に追加できるディレクティブですが、大きく分けて3つのカテゴリーに分類されます。ここでは、それぞれの特徴や使い方をイメージしやすいように、順を追って解説していきます。
1. コンポーネント(Component Directive)
コンポーネントはディレクティブの一種
技術的には、コンポーネント(@Component
)もディレクティブ(@Directive
)の拡張版として位置付けられています。ただし、コンポーネントが「UIのひとかたまり」であるのに対して、構造・属性ディレクティブは「UIの見た目や構造を変化させるための命令書」という位置づけです。
コンポーネントについては別切りで解説ページを作っておりますので以下で詳しく確認してください。
2. 構造ディレクティブ(Structural Directive)
- 何をする?
- HTMLの要素を「追加・削除」して、DOM(画面構造)自体を変化させるためのディレクティブです。
- どんなイメージ?
- 「条件がtrueのときだけ要素を表示したい」「配列の要素を繰り返し表示したい」など、動的に要素を増減する仕組みが必要なときに使います。
- なぜ便利?
- 従来ならJavaScriptでDOM操作をして要素を手動で増やしたり削除したりしていた部分を、テンプレートの記述だけで表現できる。
- 画面ロジックがHTML上で明確にわかるので、可読性も高い。
サンプルコード1 *ngIf
と*ngFor
の併用
<div *ngIf="items && items.length > 0"> <ul> <li *ngFor="let item of items">{{ item }}</li> </ul> </div>
要素が存在して、かつ1つ以上アイテムがある場合にのみ、リストを表示する構造を簡潔に表現できます。構造ディレクティブは、*
プレフィックスを使用してテンプレート上で適用されます。これにより、Angularはディレクティブの存在する要素をラップする<ng-template>
を自動的に作成し、その内容の表示を制御することができます。
サンプルコード2 *ngIf
を使用して条件に応じて要素を表示/非表示にする
<!-- 条件が真の場合のみ<p>タグを表示します --> <p *ngIf="condition">条件が真のときに表示されます</p>
サンプルコード3 *ngFor
ディレクティブを使用して配列の各アイテムに対して要素を繰り返し表示
<!-- 配列itemsの各アイテムに対して<li>タグを繰り返し表示します --> <ul> <li *ngFor="let item of items">{{ item }}</li> </ul>
3. 属性ディレクティブ(Attribute Directive)
- 何をする?
- 既存のHTML要素やコンポーネントに対して、見た目や振る舞いを変更するための追加機能を付与するディレクティブです。
- “HTMLタグそのものの構造を増減する”のではなく、“そのタグの属性やスタイルなどを動的に操作する”イメージです。
- どんなイメージ?
- 「ある条件でクラスを切り替えたい」「スタイルを動的に変更したい」など、要素の属性に関わる部分をAngularの仕組みと連動させたいときに活躍します。
- なぜ便利?
- 画面のデザインや動的変化をコード内のロジックと直接リンクできるので、UIの変更がわかりやすい。
- Sassなどのスタイル管理とも相性がよく、UIの動的変更を細かく制御できます。
代表的な属性ディレクティブ
[ngClass]
- 条件に応じてクラスを追加・削除したり、複数のクラスを同時に切り替えたりできる。
- 例:
[ngClass]="{ 'active': isActive, 'error': hasError }"
[ngStyle]
- スタイルをオブジェクト形式で動的に変更できる。
- 例:
[ngStyle]="{ 'background-color': bgColor }"
[ngModel]
- フォーム要素(入力欄など)とデータをバインドするために使う。(Template-driven formsで利用)
- その他カスタム属性ディレクティブ
- Angularが用意しているディレクティブ以外にも、自分で作成して要素の見た目や挙動を拡張できます。
サンプルコード4 ngClass
の使用例
<button [ngClass]="{ 'btn-primary': isPrimary, 'btn-disabled': isDisabled }"> ボタン </button>
サンプルコード5 ngStyle
ディレクティブを使用して要素のスタイルを動的に適用
<!-- スタイルオブジェクトに基づいて動的にスタイルを適用 --> <div [ngStyle]="{'font-size': size + 'px'}">テキストサイズを動的に変更</div>
これらのディレクティブを利用することで、Angularアプリケーション内のHTML要素の外見や振る舞いを柔軟に制御することができます。構造ディレクティブと属性ディレクティブは、それぞれDOMの構造変更と要素のプロパティ/スタイルの変更という異なる目的で使用され、アプリケーションのUIをよりダイナミックにするために重要な役割を果たします。