SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

AngularJSではじめるJavaScriptフレームワーク開発スタイル

AngularJSでカスタムディレクティブを作ってみよう

AngularJSで初めるJavaScriptフレームワーク開発スタイル 第11回

親コントローラと連携したカスタムディレクティブを作成する

 続いて、先ほど作成した例を元に、親となるコントローラと連携したディレクティブを作成します。前回の例では、テンプレートのhello属性に値を指定していないので静的なコンテンツと変わりがありませんでしたが、今回は属性を利用し、また、コントローラ内で変更する$scope変数の値に応じた表示を行うディレクティブを作成します。

 今回のサンプルは、図2のようにテンプレートで指定したhello属性の値を取得する方法と、HelloControllerで定義した$scope.message変数の値をディレクティブで取得する方法の例を示します。$scope.message変数の値は、時間経過とともに変化するものとします。

図2 コントローラと連携したカスタムディレクティブ
図2 コントローラと連携したカスタムディレクティブ

 テンプレートは前回利用したサンプルを元にリスト3のように変更します。

リスト3 HTMLテンプレート(hello2/hello.html)
<!DOCTYPE html>
<html lang="ja" ng-app="hello">
<head >
    <script type="text/javascript" src="../vendors/jquery-2.1.4.min.js"></script> <!-- (1)jQueryの利用 -->
    <script type="text/javascript" src="../vendors/angular.js"></script>
    <script type="text/javascript" src="hello.js"></script>
</head>
<body ng-controller="HelloController">  <!-- (2)HelloControllerを利用する -->
    <div hello="en"></div> <!-- (3)属性値を利用する -->
    <div hello="ja"></div>
</body>
</html>

 今回はjQueryを使ってDOMを操作しますので、(1)のようにjQueryを読み込みます[*]。また、連携するコントローラであるHelloControllerを(2)のように指定します。

 続いて、今回作成するhelloディレクティブを(3)のように記述します。指定する属性値によって表示を切り替えるために、異なる2つの値をここでは指定しておきます。

 また、実際のhelloディレクティブの実装例を示したものがリスト4です。

[*] サンプルに示したレベルであればjqLiteで十分なので、必ずしもjQueryを使う必要はありません。ただし、アプリにjQueryのプラグインを組み込むこともよくあるので、今回はその例として、DOM操作にjQueryを用いています。

リスト4 コントローラと連携したディレクティブの実装(hello2/hello.js)
(function(){
    'use strict';
    angular.module('hello',[])
        .controller('HelloController',['$timeout','$scope',HelloController])  // (1)HelloControllerの利用
        .directive('hello',[HelloDirective]);

    function HelloController($timeout,$scope){
        // (2)意図的に遅延したmessageオブジェクトを作成する
        $timeout(function(){
            $scope.message = {
                ja : 'こんにちは',
                en : 'Hello'
            };
        },1000);
        // (3)messageオブジェクトの内容を変更する
        $timeout(function(){
            $scope.message = {
                ja : 'さようなら',
                en : 'Bye Bye'
            };
        },5000);

    }
    function HelloDirective(){
        return function($scope,element,attrs){
            // (4)<div hello="ja"></div>でのhello属性を取得する
            var lang = attrs['hello'];
            // (5)コントローラ内の $scope.message[lang] の変数の変化によりDOMを操作する
            $scope.$watch('message.' + lang,function(newVal){
                if(newVal){
                    $(element).empty().append(newVal).show();
                }
                else{
                    $(element).hide();
                }
            });
        }
    }
}());

 (1)では、連携するコントローラであるHelloControllerを定義します。続いて表示の際に利用する$scope.messageオブジェクトを(2)のように作成します。

 実際の値はAjaxなどで非同期に取得することなどを想定して、$timeoutサービス使って値を遅らせて作成しています。同様に(3)でもさらに遅らせて$scope.messageの値を更新します。

 続いて、helloディレクティブの本体を実装していきます。

 (4)では、テンプレートで指定されたhello属性の値を取得しています。例では"en"もしくは"ja"という値が取得でき、表示するための変数として$scope.message.enもしくは$scope.message.jaという変数を利用します。そのため表示する変数値として利用したいところですが、実際には最初の実行時には、変数自体が未定義であり、その後、1秒後、5秒後と変数の値が変わっていきます。

 従って、その値の変化時に値を変えなければいけませんので、その変化を追跡する必要があります。

 そのための方法として$scope.$watchメソッドがあります。$scope.$watchメソッドでは、監視すべきスコープ内の変数と、コールバック関数を指定することで、$scope変数の変化に応じた処理を実装できます。

 ここでは、(5)のように$scope.$watchメソッドを使って変数の値が変更された時に、DOM操作をするようにします。このようなにコントローラなどと連携することで、先ほどのHello Worldのサンプルと同じ知識で多少複雑なことができるようになります。

次のページ
コントローラとテンプレートを組み合わせたディレクティブを作成する

この記事は参考になりましたか?

AngularJSではじめるJavaScriptフレームワーク開発スタイル連載記事一覧

もっと読む

この記事の著者

山田 祥寛(ヤマダ ヨシヒロ)

静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト」代表。主な著書に「独習シリーズ(Java・C#・Python・PHP・Ruby・JSP&サーブレットなど)」「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravelなど)」「改訂3版JavaScript本格入門」「これからはじめるLaravel実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

WINGSプロジェクト 小林 昌弘(コバヤシ マサヒロ)

WINGSプロジェクト について> 有限会社 WINGSプロジェクト が運営する、テクニカル執筆コミュニティ(代表 ...

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/8845 2015/07/31 14:00

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー