AngularJSのdirectiveとは

以下はhttp://docs.angularjs.org/guide/directive のドキュメントをだいたい和訳した感じの内容になってます。

## 概要
DOMをいじるコードを綺麗にみせるための仕組み。

## directiveの処理の流れ
http://docs.angularjs.org/guide/directive の Compilation process, and directive matchingの項より

1. parse:
HTML文字列をDOMに変換する。
2. compile:
1で変換したDOMを探索してdirectiveが必要な要素を見つけたらdirectiveのcompileを実行する。もし複数のdirectiveが必要な場合優先順位付けが行われる。
3. link: scopeとtemplateを結びつける。ここで要素に対するリスナが登録されたりscopeのwatchesがセットされたりする。

```javascript: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はオブジェクトを返すように定義する。
それぞれの値の意味は下で説明する。

```javascript: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 に当たるものを返せばよい。

```javascript: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></my-directive>
	* A: \<div my-directive="exp"> </div>
	* C: \<div class="my-directive: exp;"></div>
	* M: <!-- directive: my-directive exp -->
* template: テンプレート
* templateUrl: templateをURLで指定できる。URLの内容が読み込まれるまでcompileやlinkの処理は始まらない。
* replace: trueにするとtemplateで指定した値で現在の要素が置換される（追加でなく）
* transclude: [ngTransclude](http://docs.angularjs.org/api/ng.directive:ngTransclude)とセットで使われる。
* compile: 上で説明したdirectiveの処理の流れの2で実行される関数
* link: 同3で実行される関数

## 参考資料
[Egghead](http://egghead.io/): directiveだけでなく他のAngularJSの機能についても解説した豊富なビデオがあります。