AngularJS TIPS
ディレクティブを自作するには?(directiveメソッド)
AngularJSで、ビューの操作/生成を独立させて独自ディレクティブを作成する基本的な定義方法と使用例を説明する。
本連載で紹介してきたように、AngularJSには標準でも汎用的なディレクティブが用意されています。しかし、実践的なアプリ開発には、標準的なディレクティブだけでは事足りない場合も少なくありません。そのような場合であっても、安易にコントローラーやサービスから文書ツリーを操作するのは避けるべきです。ビューとコントローラー/サービスとが密に絡み合うことでコードの見通しが悪化する、ユニットテストを実施しにくくなる、などの問題があるためです。
ビューの操作/生成は、まずはディレクティブとして独立させるのが基本です。本稿では、ディレクティブを自作するためのdirective
メソッドについて解説していきます*1。
- *1 AngularJS 1.5では要素型のディレクティブを定義するための
component
メソッドも追加されていますが、本稿では1.4以前の環境も考慮してdirective
メソッドを優先して利用します。component
メソッドについては、後日別途解説の予定です。
[Note]拡張ディレクティブ(ライブラリ)について
AngularJSの世界では、さまざまな拡張ディレクティブも提供されています。使われることが多い機能であれば、すでに提供されている可能性が高いので、まずは既存のライブラリを検索してみるのも良いでしょう。拡張ディレクティブ(ライブラリ)に関する詳細は、拙著『AngularJSライブラリ 活用レシピ 厳選 108』(Kindle版)などの専門書も参照してください。
では、まずはごく基本的なwg-hello
ディレクティブを定義してみます。<wg-hello>
要素で「こんにちは、世界!」という文字列を出力するだけの、ごく基本的なディレクティブです。
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<meta charset="UTF-8" />
<title>AngularJS TIPS</title>
</head>
<body ng-controller="MyController">
<!-- 5wg-helloディレクティブの呼び出し-->
<wg-hello></wg-hello>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.min.js"></script>
<script>
angular.module('myApp', [])
// 1ディレクティブを定義
.directive('wgHello', function() {
// 2ディレクティブを定義するためのオブジェクトを返す
return {
// 4ディレクティブの適用箇所を指定
restrict: 'E',
// 3テンプレートを埋め込み
template: '<p style="background-color:Yellow">こんにちは、世界!</p>'
}
})
.controller('MyController', ['$scope', function($scope) {
}]);
</script>
</body>
</html>
|
ディレクティブを定義するには、directive
メソッドを利用します(1)。
[構文]directiveメソッド
directive(name, factory)
- name: ディレクティブの名前
- factory: ディレクティブを生成するファクトリー関数
引数name
には正規化された名前(「[Note]正規化された名前」参照)を指定します。また、他のディレクティブ、またはHTML標準の要素/属性とバッティングしないようにするためにも、何らかの名前空間を接頭辞として付与しておくことをお勧めします。この例であれば、「wg」がそれです(この「wg」は、筆者が所属しているコミュニティ「WINGSプロジェクト」に由来しています)。名前空間は、タイプの簡便さを考慮して、差し支えない範囲で短い名前とするのが無難でしょう。また、AngularJS標準の「ng」は利用すべきではありません。
[Note]正規化された名前
AngularJSでは、以下のような手順でディレクティブ名を正規化しています。
- 先頭の「x-」「data-」を除去
- 「-」「_」「:」で区切られた名前をcamelCase形式に変換
よって、x-wg-hello
であれば、まず「x-」を除去して「wg-hello」とし、そのあと、camelCase形式「wgHello」とします。directive
メソッドの引数name
で指定しているのは正規化された名前なので、この例であれば、実際には「wg-hello」「x_wg_hello」「data-wg-hello」などの形式で呼び出せます。
引数factory
(ファクトリー関数)は、ディレクティブを定義するためのオブジェクトを戻り値として返す必要があります(2)。ディレクティブオブジェクトには、以下のようなプロパティを指定できます。
プロパティ | 概要 |
---|---|
template | ディレクティブに適用するテンプレート(文字列) |
templateUrl | ディレクティブに適用するテンプレート(指定のファイル) |
restrict | ディレクティブの適用先(E:要素、A:属性など。詳細後述) |
trunsclude | 配下のコンテンツをテンプレートに反映するか |
multiElement | 複数の要素にまたがったディレクティブであるか |
scope | ディレクティブに適用するスコープ |
require | ディレクティブ同士の依存関係 |
priority | ディレクティブ実行の優先順位(数値が大きいものほど優先順位も高い) |
全てのプロパティは任意なので、適宜、必要に応じて組み合わせを使い分けます。この例であれば、template
プロパティを利用して、wg-hello
ディレクティブの配下に「<p>こんにちは、世界</p>」という文字列(テンプレート)を埋め込んでいます(3)。
restrict
は、ディレクティブを適用する箇所を指定するためのプロパティです(4)。設定可能な値には、以下のようなものがあります。
設定値 | 利用例 |
---|---|
E(要素) | |
A(属性) | |
C(クラス) | |
M(コメント) |
ただし、一般的には、E(要素)、A(属性)以外を利用することはほとんどありませんし、利用すべきではありません。デフォルトは「EA」(要素か属性)なので、上記のサンプルコードでは要素としてだけ呼び出せるよう、「E」としています。
このように定義されたwg-hello
ディレクティブは、標準ディレクティブと同じ要領で呼び出せることも確認しておきましょう(5)。開発者ツールから確認してみると、以下のようにディレクティブの配下にテンプレートが反映されていることも確認できます。
<wg-hello>
<p style="background-color:Yellow">こんにちは、世界!</p>
</wg-hello>
|
処理対象:自作 カテゴリ:ディレクティブ
API:angular.Module カテゴリ:ng(コアモジュール) > type(型)
※以下では、本稿の前後を合わせて5回分(第70回~第74回)のみ表示しています。
連載の全タイトルを参照するには、[この記事の連載 INDEX]を参照してください。
70. AngularJSのサービスを単体テストするには?
テスティングフレームワーク「Karma+Jasmin」を使って、AngularJSの「サービス」の単体テストを記述し、それを実行する方法を解説する。
71. AngularJSのコントローラーを単体テストするには?
テスティングフレームワーク「Karma+Jasmin」を使って、AngularJSの「コントローラー」の単体テストを記述し、それを実行する方法を解説する。
72. 【現在、表示中】≫ ディレクティブを自作するには?(directiveメソッド)
AngularJSで、ビューの操作/生成を独立させて独自ディレクティブを作成する基本的な定義方法と使用例を説明する。
73. ディレクティブで利用するテンプレートを外部ファイル化するには?(templateUrlプロパティ)
ビューの操作/生成を定義した自作ディレクティブのテンプレートを外部ファイル化して利用する方法を解説。また、ビューの中で<script>要素としてテンプレートを宣言する方法も説明する。
74. ディレクティブ配下のコンテンツをテンプレートに反映させるには?(transcludeプロパティ)
自作ディレクティブ呼び出し側で指定した「配下のコンテンツ」をテンプレートに反映させることで、そのディレクティブ要素の下に埋め込まれるHTMLコードを動的に切り替える方法を説明する。