以下はhttp://docs.angularjs.org/guide/directive のドキュメントをだいたい和訳した感じの内容になってます。
概要
DOMをいじるコードを綺麗にみせるための仕組み。
directiveの処理の流れ
http://docs.angularjs.org/guide/directive の Compilation process, and directive matchingの項より
- parse:
HTML文字列をDOMに変換する。 - compile:
1で変換したDOMを探索してdirectiveが必要な要素を見つけたらdirectiveのcompileを実行する。もし複数のdirectiveが必要な場合優先順位付けが行われる。 - link: scopeとtemplateを結びつける。ここで要素に対するリスナが登録されたりscopeのwatchesがセットされたりする。
sample.js
var $compile = '...'; // injected into your code
var scope = '...';
var html = '<div ng-bind="exp"></div>';
// Step 1: parse HTML into DOM element
var template = angular.element(html);
// Step 2: compile the template
var linkFn = $compile(template);
// Step 3: link the compiled template with the scope.
linkFn(scope);
directiveを書く
directiveはオブジェクトを返すように定義する。
それぞれの値の意味は下で説明する。
sample.js
var myModule = angular.module('...');
myModule.directive('directiveName', function factory(injectables) {
var directiveDefinitionObject = {
priority: 0,
template: '<div></div>',
templateUrl: 'directive.html',
replace: false,
transclude: false,
restrict: 'A',
scope: false,
compile: function compile(tElement, tAttrs, transclude) {
return {
pre: function preLink(scope, iElement, iAttrs, controller) { ... },
post: function postLink(scope, iElement, iAttrs, controller) { ... }
}
},
link: function postLink(scope, iElement, iAttrs) { ... }
};
return directiveDefinitionObject;
});
directiveの省略形
directive は 最低限 link function に当たるものを返せばよい。
sample.js
var myModule = angular.module('...');
myModule.directive('directiveName', function factory(injectables) {
return function(scope, element, attars) {
}
}
directiveで指定する値の意味
- priority: 同じDOM要素で複数のdirectiveが定義されている場合に用いる。値が大きいほうから順番にdirectiveが実行される。
- terminal: priorityとともに用いる。terminalをtrueにしたdirectiveよりpriorityが小さいdirectiveは実行されない。
- scope: true, false, {} の3つの値が設定でき、{} の中には更に @ or @attr, = or =attr, & or &attr の4つの値が設定できる。
- true: 現在のdirectiveのための新しいscopeが作られる。もし同じ要素で複数のdirectiveが新しいscopeを作ろうとした場合1つしか作られない。
- {}: 親scopeを継承しないscopeを生成する。
- @ or @attr: ローカル(このdirectiveの)scopeの値をDOMに追加する。
- = or =attr: 指定した値を親scopeにコピーする。どちらかの値が変更された場合はもう片方も変更される。
- & or &attr: 指定した値を親scopeのcontextで実行する。
- controller: コントローラのコンストラクタ関数を定義する。 ここで指定した関数によりpre-linkの前のタイミングでコントローラが生成される。生成されたコントローラは他のdirectiveと共有できる(requireで指定する)
- require: 現在のdirectiveのlinkに渡された他のコントローラをその名前で指定できる。もし存在しない場合エラーが発生する。先頭に?をつけることでoptionalにできる(存在しなくてもエラーが発生しない)。また、先頭に^をつけることで親要素もコントローラの検索範囲になる 。
- restrict: directiveの指定方法を定義する。EACMの4つの値がある。1つを指定したら他の方法ではdirectiveは実行されない。複数指定するときはつなげて書く("EAC"や"EM"など)
- E: <my-directive>
- A: <div my-directive="exp">
- C: <div class="my-directive: exp;">
- M:
- template: テンプレート
- templateUrl: templateをURLで指定できる。URLの内容が読み込まれるまでcompileやlinkの処理は始まらない。
- replace: trueにするとtemplateで指定した値で現在の要素が置換される(追加でなく)
- transclude: ngTranscludeとセットで使われる。
- compile: 上で説明したdirectiveの処理の流れの2で実行される関数
- link: 同3で実行される関数
参考資料
Egghead: directiveだけでなく他のAngularJSの機能についても解説した豊富なビデオがあります。