AngularJS Factoryを使った言語切り替え

これは [AngularJS Advent Calendar 2014](http://qiita.com/advent-calendar/2014/angularjs) の12/3の投稿です。

*この記事はAngularJS初心者が、AngularJSへの理解を深めるために書いた記事です。*

## 概要
AngularJSで日本語と英語の切り替えを実装する案件がありました。
仕組みとしては、画面の共通ヘッダー部に「日本語/英語」切り替えのメニューがあり、それを選択することで画面の文章や単語を任意の言語に切り替えるというものです。
それをAngularJSのFactory機能を利用し実装しました。
　　
## サンプル
実際にサンプルを記述します。
　
　
まず日本語と英語の言語ファイルを作成します。

```lang:japanese.json
{
"no":"ナンバー",
"registration_no":"登録番号",
"posting_date":"申込日",
"date_received":"受付日"
....
}
```

```lang:english.json
{
"no":"Nomber",
"registration_no":"Registration No",
"posting_date":"Posting Date",
"date_received":"Date Received",
....
}
```
　
次にFactoryを作成します。仮に「languageFactory」とします。

```lang:languageFactory.js
angular.module('sampleApp').factory('languageFactory', function () {
  var factory = {};

  // 言語ファイルのデータを格納
  factory.data = {};

  // 言語の種類リスト
  factory.typeList = ['japanese', 'english'];

  // 各言語ファイルの取得先
  factory.urlList = {
    'japanese': '/language/japanese.json',
    'english': '/language/english.json'
  };

  // 現在の言語の種類を格納
  factory.type = '';

  return factory;
});

```
　

言語を切り替えるViewとControllerを作成します。

![言語切り替えメニューイメージ.png](https://qiita-image-store.s3.amazonaws.com/0/59710/bcbc84db-872b-14c8-393e-09983bee4422.png)
言語切り替えメニューイメージ

* View

```lang:index.html
<html ng-controller="MainCtrl">
<body>
  <ul class="nav navbar-nav navbar-right">
    <li class="dropdown">
      <p data-toggle="dropdown">
        Language:  <span>{{language.type}}</span>
        <span class="caret"></span>
      </p>
      <ul class="dropdown-menu" role="menu">
        <li ng-repeat="d in languageTypeList"
            ng-click="changeLanguage(d)"><a>{{d}}</a></li>
      </ul>
    </li>
  </ul>
</body>
</html>
```

* Controller

languageFactoryを呼び出し、$scopeに定義します。
languageFactoryのtypeListを元に言語一覧を作成します。

```lang:MainCtrl.js
angular.module('sampleApp').controller('MainCtrl', function ($scope, $http, languageFactory) {

  var init = function() {

    // scopeに定義
    $scope.language = languageFactory;
    $scope.languageTypeList = $scope.language.typeList;

    // 画面による言語切り替えロジック
    $scope.changeLanguage = function(type){
      if (!angular.equals($scope.languageType, type)) {

        // 言語ファイルの取得
        $http.get($scope.language.urlList[type]).then(function(res){

          // 言語の種類をlanguage.typeに格納
          $scope.language.type = type;

          // 言語データをlanguage.dataに格納
          $scope.language.data = res.data;

        }, function(res){
          // 取得失敗処理
        });
      }
    };
  };
  init();

});

```

一覧をクリックすることで`changeLanguage()`が処理されます。
`changeLanguage()`の引数には言語名が設定され、それが現在のtypeとしてヘッダーメニューの「Language: {言語の種類}」に表示されます。
　　
　　

次に言語を表示するViewとControllerを作成します。

* View

```lang:demo.html
<div ng-controller="DemoCtrl">
  <div>{{language.data.no}} : 12345</div>
  <div>{{language.data.registration_no}} : 98765</div>
</div>
```

* Controller

languageFactoryを呼び出し、$scopeに定義します。

```lang:DemoCtrl.js
angular.module('sampleApp').controller('DemoCtrl', function ($scope, $http, languageFactory) {

  // scopeに定義
  $scope.language = languageFactory;

});

```
　
このdemo.htmlをindex.htmlにincludeすれば言語切り替えの完成です。
　
## まとめ
FactoryはいわゆるAngularJSの「グローバル変数」のようなものだと認識しています。
ControllerとController間で共通の変数を持つことができ、片方のscopeが値が変更された場合、もう一方のControllerの値を変更することができます。

このサンプルの場合は、実際に言語切り替え処理をしているのはMainCtrl.jsのみで、あとのControllerは単純にlanguageFactoryをscopeに定義しているだけです。
あとはAngularJSがデータバインドでFactoryを定義している全Controllerの値を勝手に変更してくれます。
　
## お知らせ
12月10日（水）19:30からセミナーを開催します。
[AngularJSとReflexWorksで始めるSPA開発 ～もうサーバー側で悩まなくて大丈夫～](http://acrovision.connpass.com/event/9957/)
AngularJSを利用したサーバー通信の方法等、興味持たれた方は是非気軽にご参加ください。