[AngularJS] 5. イベント処理≪改訂≫

---
[目次](http://qiita.com/Koizumi-Greenwich/items/3e327e3331b2f728797e)
≪前の記事 4.[$watch≪改訂≫](http://qiita.com/Koizumi-Greenwich/items/539ccc4b995305d7ff00)
≫次の記事 6.[カスタムフィルタ≪改訂≫](http://qiita.com/Koizumi-Greenwich/items/87e447fd329fd7c00fa6)

---
*【改訂】3. サービス定義 の改訂に合わせてサンプルコードを改訂しました。*

#イベント・ディレクティブ
AngularJSでは、click、mouseenter などのDOMイベントの指定を **ディレクティブ** で行い、その処理を **スコープに定義した関数** で定義します。

##ng-click
HTML要素をクリックしたときに発生するイベントを指定します。

```text:ng-click書式
< ... ng-click="関数名(引数, ...)">....</ ... >
```

**関数名**は、別途コントローラで定義するスコープの関数の名前です。この要素がクリックされるとここで指定した関数が呼び出されイベントの処理が行われます。

イベント処理（関数内）でイベント発生元の要素オブジェクトなど、イベント情報が必要になる場合は、引数に **$event** を渡します。
\$event は *DOMイベントオブジェクト*や *jQueryイベントオブジェクト*と同様の、イベント情報を持つオブジェクトです。

```text:ng-click書式
< ... ng-click="関数名($event, 引数, ...)">....</ ... >
```

その他、引数の数は自由に増やせますので、必要なだけ指定することができます。

##ng-mouseenter, ng-mouseleave
要素の領域にマウスポインタが出入りした時に発生するイベントを指定します。

```text:ng-click書式
< ... ng-mouseenter="関数名(引数, ...)" ng-mouseleave="関数名(引数, ...)">....</ ... >
```

```text:ng-click書式
< ... ng-mouseenter="関数名($event, 引数, ...)" ng-mouseleave="関数名($event, 引数, ...)">....</ ... >
```

ng-click と同様に \$event を渡すことで イベント情報を取り扱うことができます。


##その他
このように、JavaScriptのイベント -- onclick, onmouseenter といった各イベントに対応するディレクティブが用意されています。詳しくは [公式リファレンス](https://docs.angularjs.org/api)、または [日本語リファレンス](http://js.studio-kingdom.com/angularjs) の **ディレクティブ** の章を参照してください。

#サンプルコード
以下のサンプルコードでは、focus/blur イベントを利用して、フィールドへのフォーカスのIN/OUTによってフィールドの色を変化させています。

色の変化（CSSの制御）を簡易に行うため jQuery を利用します。

HTMLの各input要素に **ng-focus**、 **ng-blur** ディレクティブを指定し、それぞれ focusIn()、focusOut() を呼び出すようにしています（$event を渡しています）。

またコントローラ内で、focusIn()、focusOut()両関数を定義しています。$event オブジェクトを受け取り、フォーカスが出入りした要素を対象にjQueryでCSSを制御しています。


```html:sample05.html
<!DOCTYPE html>
<meta charset="UTF-8">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script>
<script>
/**
 * アプリケーション モジュール オブジェクトの定義
 */
(function() {
    var module = angular.module("sampleModule", []);
})();

/**
 * 商品モデルクラス定義
 */
(function(module) {
    module.service("Product", function(){
        /**
         * コンストラクタ
         */
        var product = function() {
            this.name  = "";
            this.price = 0;
            this.qty   = 0;
            this.total = 0;
        }
        var p = product.prototype;

        /**
         * 合計を計算する
         */
        p.calcTotal = function() {
            this.total = this.price * this.qty;
        }

        return product;
    });
})(angular.module("sampleModule"));

/**
 * コントローラの定義
 */
(function(module) {
    /**
     * SampleController
     */
    module.controller("sampleController", function($scope, $timeout, Product) {
        // Productクラスのインスタンスを $scope にセットする
        $scope.product = new Product();
            
        /*
         * $scope の値の変化を監視する
         */
        // product.price, product.gty 変化イベント
        $scope.$watchGroup(["product.price", "product.qty"], function(newValue, orldValue, scope) {
            // product.price, product.gtyに変化があれば、合計額を計算する
            scope.product.calcTotal();
        });
        
        /*
         * イベント処理
         */
        // フィールドにフォーカスが入った時
        $scope.focusIn = function(event) {
            // フィールドの背景を薄黄色にする
            $(event.target).css("backgroundColor", "#ffffcc");
        }
        // フィールドからフォーカスがはずれた時
        $scope.focusOut = function(event) {
            // フィールドの背景を白にもどす
            $(event.target).css("backgroundColor", "#ffffff");
        }
    });
})(angular.module("sampleModule"));
</script>
<!-- sampleModule テンプレート -->
<div ng-app="sampleModule">
    <!-- sampleController テンプレート -->
    <div ng-controller="sampleController" ng-cloak>
        <dl>
            <dt>商品名</dt>
            <dd><input type="text" name="name" ng-model="product.name" ng-focus="focusIn($event)" ng-blur="focusOut($event)"></dd>
            <dt>単価</dt>
            <dd><input type="number" name="price" ng-model="product.price" ng-focus="focusIn($event)" ng-blur="focusOut($event)"> 円</dd>
            <dt>数量</dt>
            <dd><input type="number" name="qty" ng-model="product.qty" ng-focus="focusIn($event)" ng-blur="focusOut($event)"> 個</dd>
            <dt>合計</dt>
            <dd>{{product.total | number}} 円</dd>
        </dl>
    </div>
</div>
```

---
[目次](http://qiita.com/Koizumi-Greenwich/items/3e327e3331b2f728797e)
≪前の記事 4.[$watch≪改訂≫](http://qiita.com/Koizumi-Greenwich/items/539ccc4b995305d7ff00)
≫次の記事 6.[カスタムフィルタ≪改訂≫](http://qiita.com/Koizumi-Greenwich/items/87e447fd329fd7c00fa6)

---