Deep Insider の Tutor コーナー
>>  Deep Insider は本サイトからスピンオフした姉妹サイトです。よろしく! 
AngularJS TIPS

AngularJS TIPS

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

2016年9月26日

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

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

 ディレクティブオブジェクトcontrollerプロパティを使って、コントローラー付きのディレクティブを作成してみましょう。

 例えば以下は、クリックによって本文パネルを開閉できる<wgCollapsedPanel>要素(ディレクティブ)の例です。<wgCollapsedPanel>要素の構文は、以下の通りです。

[構文]<wg-collapsed-panel>要素(自作)

<wgCollapsedPanel title="str">body</wgCollapsedPanel>

  • str: パネルのタイトル
  • body: パネル本文

 以下は、その具体的なコードです。

HTML
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<meta charset="UTF-8" />
<title>AngularJS TIPS</title>
</head>
<body ng-controller="MyController">
<wg-collapsed-panel title="WINGSプロジェクト">WINGSプロジェクトは、主にサーバーサイド技術に関する書籍/記事執筆、翻訳、講演などを行うコミュニティです。<br />
メンバーのほとんどが他の仕事を持つ兼業ライターです。</wg-collapsed-panel>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.min.js"></script>
<script>
angular.module('myApp', [])
  .directive('wgCollapsedPanel', function() {
    return {
      restrict: 'E',
      // 1属性/本文からコンテンツを受け取れるように設定
      scope: {
        title: '@'
      },
      // 5分離スコープをコントローラーにバインド
      bindToController: true,
      transclude: true,
      // 3タイトルのクリックでonclickメソッドを呼び出し
      template: '<div style="background-color: #006; color: #fff; padding: 5px;" ng-click="ctrl.onclick()">{{ctrl.title}}</div>'
        + '<div style="border: solid 1px Silver;margin: 0px; padding: 10px;" ▲ng-if="ctrl.show" ng-transclude></div>',
      // 2ディレクティブの動作を定義
      controller: function() {
        this.show = false;
        this.onclick = function() {
          this.show = !this.show;
        }
      },
      // 4コントローラーの別名
      controllerAs: 'ctrl'
    };
  })
  .controller('MyController', ['$scope', function($scope) {
  }]);
</script>
</body>
</html>
マウスクリックによってパネルを開閉するためのコード(controller.html)
[WINGSプロジェクト]をクリック

[WINGSプロジェクト]をクリック

マウスをクリックすると、本文部分が表示/非表示
マウスをクリックすると、本文部分が表示/非表示

 まずは、scopetranscludeプロパティ(1)で属性/本文からコンテンツを受け取れるように設定します。これらのプロパティについては、それぞれ別稿「TIPS:ディレクティブ配下のコンテンツをテンプレートに反映させるには?」「TIPS:ディレクティブで属性を設定するには?」を参照してください。属性名と、分離スコープのプロパティ名とが等しい場合には、単に@と表記できるのでした(@titleとしても同じ意味です)。

 そして、ディレクティブで利用するイベントハンドラーなどを、controllerプロパティで定義します(2)。この例であれば、onclickイベントリスナーで変数showの値を反転させています。この変数showは、テンプレートとして指定された<div>要素3のHTMLコード上で、ng-ifディレクティブにひも付けされています。これによって、タイトル部分をクリックするたびに本文パネルの表示/非表示が切り替わるというわけです。

 controllerAsプロパティはコントローラーの別名(本稿の例ではctrl)を表します(4)。これによって、テンプレート内でも「別名.メンバー」(例:ctrl.show)でコントローラーのメンバーにアクセスできるようになります。また、bindToControllerプロパティで分離スコープのメンバーもコントローラーにバインドし、同じく「別名.メンバー」でアクセスできるようにしておきます(5)。

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

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

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

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

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

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

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

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

AngularJS TIPS
77. 【現在、表示中】≫ 自作ディレクティブの挙動を定義するには?(controller/controllerAs/bindToControllerプロパティ)

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

AngularJS TIPS
78. AngularJSのディレクティブを単体テストするには?

テスティングフレームワーク「Karma+Jasmin」を使って、AngularJSの「ディレクティブ」の単体テストを記述し、それを実行する方法を解説する。

サイトからのお知らせ

Twitterでつぶやこう!