IDCF テックブログ

IDCF テックブログ

クラウド・データセンターを提供するIDCフロンティアの公式テックブログ

AngularJS開発TIPS(前編)

こんにちは。UX開発部の樋代です。

今回はSingle Page Application をAngularJSで構築する際のポイントを紹介します。AngularJSをプロジェクトに導入を検討している方向けにまとめました。

AngularJS
(引用)https://angularjs.org/

JavaScriptのフレームワーク「AngularJS」は機能が豊富な分、実際プロジェクトに導入する際には機能の選定に悩む部分があると思います。IDCフロンティアのサービスでは、AngularJSを、コンテンツキャッシュ、オブジェクトストレージ、RDS、Yahoo!ビッグデータインサイトなどで利用しています。

※2016年10月1日より、サービス名称が「Yahoo!ビッグデータインサイト」から「トレジャーデータサービス by IDCF」に変更となっております。

AngularJSには公式blogでも紹介されているコーディングスタイルのガイドラインがあります。 https://github.com/johnpapa/angular-styleguide

公式のガイドラインで特に知っておいた方がいいことや、QiitaやStack Overflowなどのユーザーコミュニティで話題になっていたことを開発のTIPSとしてまとめましたので、一度ご覧頂ければと思います。

AngularJSについてこれから勉強する方

Web上では、公式ページ以外にもこちらの日本語サイトが丁寧に解説されており、AngularJSの機能や仕組みの概念を理解していただけると思います。
http://angularjsninja.com/
http://js.studio-kingdom.com/angularjs/guide/introduction

また、AngularJSに関する書籍は2014年に何冊か出版されました。まずは書籍で概念を理解されると良いと思います。こちらの書籍が大変参考になりました。

「AngularJSリファレンス」
www.amazon.co.jp/dp/4844336681

こちらをご覧になった上で、このブログを実際のプロジェクトへ導入する際の参考にしていただければと思います。

AngularJS開発TIPS

前編と後編2回に分けてお伝えします。

【前編】
1.ServiceとFactoryの使い分け
2.URLのルーティングにはUI-Routerを使う
3.画面操作の多い画面では複数のController、Viewに分割した設計をする

【後編】
4.複数のController間のデータ共有にはShared Serviceを使う
5.サーバーサイドのURLをRESTで設計できる場合、AngularJSのRESTクライアントを利用できる。
6.Ajaxリクエストの共通処理はインターセプターで実装する

1.ServiceとFactoryの使い分け

複数のControllerで共有するロジックを共通クラスにまとめると、コードをシンプルに保ち、メンテナンス性を良くする事ができます。 AngularJSには共通クラスを作る仕組みとして、「Service」と「Factory」があります。実際に共通クラスを設計する時、ServiceとFactoryをどのように使い分けるか悩む方が多いのではないでしょうか。 プロジェクトで標準化する際のおすすめは、
● インスタンス化させずに使うメソッドを持つクラスをService
● インスタンス化して使うクラスをFactory
で設計することです。

そもそものインスタンス化で判断に迷う場合、最初はServiceだけを使っていく方針でもいいと思います。ServiceとFactoryを比較すると、インスタンス化の仕方が違うだけで、どちらもシングルトンなオブジェクトです。IDCフロンティアのオブジェクトストレージで利用した際には、基本的に共通クラスはServiceで作りました。

以下、FactoryとServiceのサンプルコードです。

サンプルコード

Factoryの定義

(function (angular) {
angular.module('myApp.sample').factory('SampleFactory', SampleFactory);

  function SampleFactory() {
    var factory = function(name) {
      this.name = name;
      this.hello = function () {
        console.log('Hello testFactory',this.name);
      }
    }
    return factory;
  }
}(angular));

Serviceの定義

(function (angular) {
  angular.module('myApp.sample').service('SampleService', SampleService);
  function SampleService () {
    this.hello = function () {
      console.log('Hello SampleService');
    }
  }
}(angular));

Serivce、Factoryの利用方法

(function (angular) {
  //ServiceとFactoryの実装サンプル
  angular.module('myApp.sample').controller('SampleController', SampleController);

  function SampleController($scope, SampleService, SampleFactory) {
    //Serviceのメソッドを実行
    SampleService.hello();

    //Factoryをインスタンス化しメソッドを実行
    var factory = new SampleFactory('AngularJS');
    factory.hello();
  }
})(angular);

ServiceとFactoryの機能的な違い

いくつか違いがありますが、特徴的な違いはこちらの2点だと思います。

  • インスタンス化できる
  • オブジェクト以外をFactoryとして作ることができる

例えばこちらは公式ページのサンプルコードですが、オブジェクトではなく、文字列を最後に文字列自体を返しています。

(引用)公式ページ https://docs.angularjs.org/guide/providers

myApp.factory('apiToken', ['clientId', function apiTokenFactory(clientId) {
  var encrypt = function(data1, data2) {
    // NSA-proof encryption algorithm:
    return (data1 + ':' + data2).toUpperCase();
  };

  var secret = window.localStorage.getItem('myApp.secret');
  var apiToken = encrypt(clientId, secret);

  return apiToken;
}]);

IDやトークンなどの値自体をControllerにインジェクションしたい場合、有効な方法です。 この方法の懸念としては、インジェクションするものが増えていったときに可視性やメンテナンス性が悪くなることです。また、設計時点から、どのドメインをFactoryとして設計するということは結構難しいのではないかと思います。

そのため何かのIDやトークンを生成するような仕組みはServiceのメソッドとして実装し、Factoryとして独立させた方がいい要件が出てきた場合、切り出すのがいいのではないかと思います。

2.URLのルーティングにはUI-Routerを使う

URLのルーティングとは、URLの変更に合わせてView、Controllerを切り替える仕組みです。 これからAngularJSを導入する方は、UI-Routerを使うことがおすすめです。AngularJS標準で持っているng-routerはルーティングとしての機能が弱く、画面上の複数のViewに対するルーティングや、Viewをネストしたルーティングができません。UI-Routerを使うとその問題は解決できます。

NewRouterかUI-Routerか

AngularJS1.4からNewRouterという新しいルーターも利用できるようになりました。 https://angular.github.io/router/getting-started

こちらは現在開発が進められているAngular2でも利用できるという新しいルーターです。UI-Routerとどちらを採用するか悩みますが、現状はUI-Routerがオススメです。Angular2が現在仕様が確定していないということもありますし、オフィシャルblogで紹介しているスタイルガイドでもUI-Routerが薦められています。

参考
https://github.com/johnpapa/angular-styleguide#routing
http://b.denkizakana.com/2014/02/angularui-router.html

3.画面操作の多い画面では複数のController、Viewに分割した設計をする

AngularJSでは、画面上のボタンを押したときに実行される処理をControllerのメソッドとして実装します。そのため、画面上の操作が沢山ある場合、Controllerへ実装するメソッドが増えていく事になります。 そのような画面でひとつのControllerに画面上の操作をするメソッドを実装していくと、Controllerの見通しが悪くなり、メンテナンスが困難になります。これはサーバーサイドのロジックと同様と考えてもらうと分かりやすいと思います。

オブジェクトストレージコントロールパネルのサンプル画面

オブジェクトストレージコントロールパネル

画面での操作の数が増えるほど、Controllerへの実装量が増えると思うので、操作の多い画面は、画面を細分化し、それぞれにControllerを割り当てるとControllerのメンテナンスがしやすくなると思います。

次回のエントリーも引き続き、AngularJS開発TIPSを後編としてお伝えします。ではでは。

<連載記事>
Copyright © IDC Frontier Inc.