134
Help us understand the problem. What are the problem?

More than 5 years have passed since last update.

posted at

updated at

Organization

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がセットされたりする。
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の機能についても解説した豊富なビデオがあります。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Sign upLogin
134
Help us understand the problem. What are the problem?