Edited at

AngularJSのdirectiveとは

More than 5 years have passed since last update.

以下は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がセットされたりする。


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: <!-- directive: my-directive exp -->



  • template: テンプレート

  • templateUrl: templateをURLで指定できる。URLの内容が読み込まれるまでcompileやlinkの処理は始まらない。

  • replace: trueにするとtemplateで指定した値で現在の要素が置換される(追加でなく)

  • transclude: ngTranscludeとセットで使われる。

  • compile: 上で説明したdirectiveの処理の流れの2で実行される関数

  • link: 同3で実行される関数


参考資料

Egghead: directiveだけでなく他のAngularJSの機能についても解説した豊富なビデオがあります。