AngularJS TIPS
自作ディレクティブの挙動を定義するには?(controller/controllerAs/bindToControllerプロパティ)
テンプレートに基づき出力されるHTMLコードの内容を、イベントハンドラーなどを活用して動的に切り替えるために、コントローラー付きの独自ディレクティブを作成する方法を説明する。
ディレクティブオブジェクトのcontroller
プロパティを使って、コントローラー付きのディレクティブを作成してみましょう。
例えば以下は、クリックによって本文パネルを開閉できる<wgCollapsedPanel>
要素(ディレクティブ)の例です。<wgCollapsedPanel>
要素の構文は、以下の通りです。
[構文]<wg-collapsed-panel>要素(※自作)
<wgCollapsedPanel title="str">body</wgCollapsedPanel>
- str: パネルのタイトル
- body: パネル本文
以下は、その具体的なコードです。
<!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>
|
[WINGSプロジェクト]をクリック
まずは、scope
/transclude
プロパティ(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]を参照してください。
74. ディレクティブ配下のコンテンツをテンプレートに反映させるには?(transcludeプロパティ)
自作ディレクティブ呼び出し側で指定した「配下のコンテンツ」をテンプレートに反映させることで、そのディレクティブ要素の下に埋め込まれるHTMLコードを動的に切り替える方法を説明する。
75. ディレクティブで属性を設定するには?(scopeプロパティ)
自作ディレクティブ呼び出し側で指定した「属性の値(文字列)」をテンプレートに反映させることで、そのディレクティブ要素の下に埋め込まれるHTMLコードを動的に切り替える方法を説明する。
76. 自作ディレクティブの属性にAngular式や関数を設定するには?(scopeプロパティ)
自作ディレクティブ呼び出し側で指定した「属性の値(Angular式や関数)」をテンプレートに反映させることで、そのディレクティブ要素の下に埋め込まれるHTMLコードを動的に切り替える方法を説明する。
77. 【現在、表示中】≫ 自作ディレクティブの挙動を定義するには?(controller/controllerAs/bindToControllerプロパティ)
テンプレートに基づき出力されるHTMLコードの内容を、イベントハンドラーなどを活用して動的に切り替えるために、コントローラー付きの独自ディレクティブを作成する方法を説明する。
78. AngularJSのディレクティブを単体テストするには?
テスティングフレームワーク「Karma+Jasmin」を使って、AngularJSの「ディレクティブ」の単体テストを記述し、それを実行する方法を解説する。