サンプルコードを使ってAngularJSの基本的なカスタムディレクティブの作成方法をまとめてみました。
デモとコードサンプルはこちら。
(1)サンプルコードの仕様
商品リストを表示する下記内容を”productsList”という名前でカスタムディレクティブを使って書き換えてみます。
(カスタムディレクティブ未使用) <div ng-controller="cus1Ctrl"> <ol> <li ng-repeat='item in products'> {{item.product_name}} : {{item.price | number:0}}円 </li> </ol> </div> (カスタムディレクティブ使用) <div ng-controller="cus1Ctrl"> <div products-list="products"></div> </div>
(2)カスタムディレクティブを作成
var demoApp = angular.module('demoApp', []); demoApp.directive("productsList", function () { return { link: function (scope, element, attrs) { scope.data = scope[attrs["productsList"]]; }, scope: true, template: "<ol><li ng-repeat='item in data'>{{item.product_name}} : {{item.price | number:0}}円</li></ol>", restrict: "A" } });
1)カスタムディレクティブの定義
・モジュールのdirective(directive名,ファクトリ関数)メソッドを使って定義。
demoApp.directive(“productsList”, function () {
上記ディレクティブによって、HTMLビュー内の”products-list”と記述された要素、属性がtemplateで定義した内容に置換されます。
・ディレクティブの名前は大文字小文字を区別し、”productsList”のようにcamelCaseで正規化される。
HTMLは大文字小文字を区別しないので”products-list”のように小文字の”-“区切りを使用します。
2)scope属性
サンプルでは、scope: trueと指定し、親のスコープ(この例では”cus1Ctrl”コントローラ)を継承した上でカスタムディレクティブ専用に新しい子スコープを生成します。
scope属性を明示的に指定していない場合のデフォルトは、scope: falseでカスタムディレクティブは親のスコープを使用し、自由に更新することも出来ます。
3)リンク関数
HTML内のディレクティブとスコープ内のデータを連結する役割を持ちます。
●リンク関数の引数
①scope
・ディレクティブが適用されるビュー内のscope。
scopeでtrueと設定しているので”cus1Ctrl”コントローラの$scope.productsで定義しているデータを参照する事が出来ます。
②element
・カスタムディレクティブが適用される対象のHTML要素のjqLiteオブジェクトで、jqLiteを使ってDOM操作をナビゲート、操作する事が出来る。
※jqLite
AngularJSに同梱されているjQueryの簡易版。
https://docs.angularjs.org/api/ng/function/angular.element
・このサンプルでは下記のように使用しているのでdiv要素となる。
<div products-list=”products”>
③atts
・ディレクティブが適用される対象のHTML要素の属性名(正規化された名前)と値のペアのハッシュオブジェクト。
このサンプルでは、カスタムディレクティブをdiv要素の属性として使用しているので、products-listという属性に指定された値をattrs[“productsList”]で取得出来ます。
attrs[“productsList”]で属性に指定した値”products”が取得できるので、scope[attrs[“productsList”]]で”cus1Ctrl”コントローラの$scope.productsを参照できます。
4)restrict属性
カスタムディレクティブはデフォルトでは属性名として利用できるようになっていて、要素名やクラス名として指定する事も出来ます。
○属性名で指定
restrict: ‘A’(デフォルト)
例)
<div products-list=”products”>
○要素名で指定
restrict: ‘E’
例)
<products-list list-source=”products”>
この例では、”products”という値をlist-sourceという属性を使って渡しています。
○クラス名で指定したい場合
restrict: ‘C’
例)
<div class=”products-list: products”>
○要素名または属性名を指定したい場合
restrict: ‘AE’
5)template、templateUrl属性
・カスタムディレクティブ内に挿入するHTMLを指定する。
templateオプションはインラインでHTMLを記述し、templateUrlオプションは、外部ファイルのパスを指定し、ファイルに記述したHTMLをインクルードします。