AngularJS Directive チュートリアル STEP6〜STEP8

blog1.mammb.com


Step6 transclude

transclude はディレクティブのコンテンツに外部スコープを適用可能とする。

コントローラで $scope.value を定義し、

  .controller('AppCtrl', function($scope) {
    $scope.value = 'hello'
  })

htmlでは以下のようにディレクティブのコンテンツとしてvalueを参照する。

  <div my-div>contents {{value}}</div>

ディレクティブでは transclude を true に設定し、テンプレートにng-transcludeを指定。

  .directive('myDiv', function() {
    return {
      restrict: 'A',
      scope: {},
      transclude: true,
      template: '<ol><li><div ng-transclude></div></li><ol>'
    };
  });

scopeには隔離スコープを指定しているため、コントローラのスコープにある value はディレクティブから参照できないが、 transclude の指定によりテンプレート中の ng-transclude が注入ポイントとなり、外部スコープにより解決されたコンテンツの埋め込みが行われる。

ブラウザ上の表示は以下のようになる。

1. contents hello

Step7 link()

ディレクティブからDOMを更新する場合にlinkオプションが利用できる。 ディレクティブを以下のように書き換える

angular.module('app', [])
  .controller('AppCtrl', function($scope) {
  })
  .directive('myDiv', function() {
    return {
      restrict: 'A',
      link: function(scope, element, attrs) {
        element.html("This is the new content");
      }
    };
  });

htmlで以下のように適用すると、

  <div my-div>will be replaced</my-div>

ブラウザでは以下の表示となる。

This is the new content

link オプションには以下が引数として渡される

  • scope Angularのスコープオブジェクト
  • element このディレクティブにマッチしたjqLiteでラップされた要素
  • attrs 正規化された属性名とそれらに一致する値のオブジェクト

Step8 compile()

link オプションと同様のことが compile オプションでもできる。 ただし、compileオプションの場合は、HTML テンプレートのコンパイル時に directives を見つけた段階で呼び出される。 これはたとえば ng-repeat の内部にディレクティブが定義してあった場合に compile() は一度だけ呼び出されるということ。 一方、link()の場合は繰り返しの度に呼び出される。 compile と link の両方が定義されていた場合には link は呼び出されない。link の呼び出しが必要な場合には、compile の戻り値として link() 関数を返却する必要がある。