AngularJS TIPS

AngularJS TIPS

ディレクティブで属性を設定するには?(scopeプロパティ)

2016年9月26日

自作ディレクティブ呼び出し側で指定した「属性の値(文字列)」をテンプレートに反映させることで、そのディレクティブ要素の下に埋め込まれるHTMLコードを動的に切り替える方法を説明する。

  • このエントリーをはてなブックマークに追加

 別稿「TIPS:ディレクティブ配下のコンテンツをテンプレートに反映させるには?」では、ディレクティブ本体のコンテンツによって、出力を動的に切り替える方法について解説しました。本稿では、引き続いて、ディレクティブに対して属性経由で任意の情報を渡す方法について解説します。

 以下は、wg-name属性で指定された名前に基づいて、「おはようございます、●○さん!」のようなメッセージを生成する<wg-hello-scope>ディレクティブの例です。まずは、具体的なコードを見ていきましょう。

HTML
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<meta charset="UTF-8" />
<title>AngularJS TIPS</title>
</head>
<body ng-controller="MyController">
<!-- 3独自ディレクティブにwg-name属性を指定-->
<wg-hello-scope  wg-name="山田太郎"></wg-hello-scope>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.min.js"></script>
<script>
angular.module('myApp', [])
  .directive('wgHelloScope', function() {
    return {
      restrict: 'E',
      // 1nameプロパティ(スコープ)とひも付くwg-name属性を定義
      scope: {
        name: '@wgName'
      },
      // 2テンプレートの中でnameプロパティ(=wg-name属性)の値を参照
      template: '<p style="background-color:Yellow">おはようございます、{{name}}さん!</p>'
    }
  })

  .controller('MyController', ['$scope', function($scope) {
  }]);
</script>
</body>
</html>
属性経由でディレクティブにパラメーター(文字列)を渡すためのコード(scope.html)
wg-name属性で指定した名前に応じて挨拶を生成
wg-name属性で指定した名前に応じて挨拶を生成

 ディレクティブに対して属性を定義するには、scopeプロパティを利用します(1)。scopeプロパティには「プロパティ名: 属性」のハッシュ形式で、ディレクティブが属するスコープと属性とをひも付けています*1。ここでは、wg-name属性で指定した値を、ディレクティブのスコープ(nameプロパティ)にひも付けています。

 「@」については、とりあえずは属性値がそのままスコープオブジェクトにセットされると理解しておいてください。詳しくは別稿「TIPS:自作ディレクティブの属性にAngular式や関数を設定するには?」で説明しています。

  • *1 scopeプロパティにハッシュを渡すことで、ディレクティブは上位のスコープからは独立した(=継承関係を持たない)新たなスコープを生成します。これを「隔離スコープ」または「分離スコープ」といいます。

 スコープオブジェクト(のプロパティ)に渡された属性値は、そのままテンプレートから参照できます(2)。ここでは、wg-name属性を1つだけ宣言していますが、もちろん、必要に応じて、複数の属性を列挙しても構いません。

[Note]「@」による属性名の省略

 属性の名前と、スコープオブジェクトのプロパティとが等しい場合には、以下のように属性名を省略することもできます。

JavaScript
scope: {
  name: '@'
}
属性名の省略

 これで「name属性の値を、同名のnameプロパティにセットしなさい」という意味になります。

 果たして、3のように<wg-hello-scope>ディレクティブにwg-name属性を指定でき、その値が結果にも反映されていることが確認できます。

scopeプロパティにfalseを指定した場合

 scope: falseとした場合、現在のスコープ(=コントローラーのスコープ)をそのまま利用することもできます。先ほどのサンプルを、以下のように書き換えてみましょう。

JavaScript
angular.module('myApp', [])
  .directive('wgHelloScope', function() {
    return {
      restrict: 'E',
      scope: false,
      template: '<p style="background-color:Yellow">おはようございます、{{name}}さん!</p>'
    }
  })

  .controller('MyController', ['$scope', function($scope) {
    $scope.name = '山田次郎';
  }]);
現在のスコープオブジェクトをそのまま利用するコード(scope_false.html)

 果たして、コントローラーのスコープで設定された情報(=nameプロパティの値)がディレクティブにも反映されることが確認できます。

 この方法を使えばディレクティブの設定はカンタンになりますが、半面、ディレクティブとコントローラーとが密接に絡み合うという意味で、望ましい状態ではありません(コントローラーのスコープオブジェクトは、いつもディレクティブが要求するプロパティ――この場合であれば、nameプロパティを持っていなければなりません)。

 原則として、ディレクティブを利用する際には分離スコープ(=scopeプロパティにハッシュを指定する方法)を優先して利用してください。

処理対象:ディレクティブ カテゴリ:基本
処理対象:自作 カテゴリ:ディレクティブ
API:angular.Module カテゴリ:ng(コアモジュール) > type(型)

※以下では、本稿の前後を合わせて5回分(第73回~第77回)のみ表示しています。
 連載の全タイトルを参照するには、[この記事の連載 INDEX]を参照してください。

73. ディレクティブで利用するテンプレートを外部ファイル化するには?(templateUrlプロパティ)

ビューの操作/生成を定義した自作ディレクティブのテンプレートを外部ファイル化して利用する方法を解説。また、ビューの中で<script>要素としてテンプレートを宣言する方法も説明する。

74. ディレクティブ配下のコンテンツをテンプレートに反映させるには?(transcludeプロパティ)

自作ディレクティブ呼び出し側で指定した「配下のコンテンツ」をテンプレートに反映させることで、そのディレクティブ要素の下に埋め込まれるHTMLコードを動的に切り替える方法を説明する。

75. 【現在、表示中】≫ ディレクティブで属性を設定するには?(scopeプロパティ)

自作ディレクティブ呼び出し側で指定した「属性の値(文字列)」をテンプレートに反映させることで、そのディレクティブ要素の下に埋め込まれるHTMLコードを動的に切り替える方法を説明する。

76. 自作ディレクティブの属性にAngular式や関数を設定するには?(scopeプロパティ)

自作ディレクティブ呼び出し側で指定した「属性の値(Angular式や関数)」をテンプレートに反映させることで、そのディレクティブ要素の下に埋め込まれるHTMLコードを動的に切り替える方法を説明する。

77. 自作ディレクティブの挙動を定義するには?(controller/controllerAs/bindToControllerプロパティ)

テンプレートに基づき出力されるHTMLコードの内容を、イベントハンドラーなどを活用して動的に切り替えるために、コントローラー付きの独自ディレクティブを作成する方法を説明する。

イベント情報(メディアスポンサーです)

Twitterでつぶやこう!


Build Insider賛同企業・団体

Build Insiderは、以下の企業・団体の支援を受けて活動しています(募集概要)。

ゴールドレベル

  • グレープシティ株式会社
  • 日本マイクロソフト株式会社