Yeomanを使ってAngularJSによるAPIリクエストと非同期の画面更新を高速実装する

f:id:watass:20150620165606p:plain

過去の記事からもわかっていただけるかと思うのですが、AWSやらFuelPHPやら、どちらかというとバックエンドの仕組みやインフラの仕組み作りを楽しいんですよね。
そんな感じで色々自分なりにやりつつも「あー、やっぱり自作アプリぐらい作っておきたいなぁ」と思い、FuelPHPでちまちま書いていたのですが、全然続かないわけですよ。
なぜか。それは成果物の見た目がかっこよくないからです。いくら頑張ってきれいなコードを書いたところで、できたアプリがダサいようでは、機能拡張もやる気になりませんよね。

というわけで、フロントエンド初心者丸出しの私がちょいとググって良さそうだったYeomanを使って、AngularJSを使ってAPIレスポンスのJSONを取得、非同期に画面を更新するというバックエンドとの連携部分をサクッと実装してみましたので備忘録として残しておきます。

Yeomanとは

Yeomanとはフロントエンド開発における便利ツールをまとめて提供してくれるツールです。フロントエンド開発ではjQueryやらAngularJSやらBootstrapやら必要なパッケージが多く、管理が面倒なことが多いとのことですが、それらを対話式のインターフェイスで必要なパッケージを準備し、管理してくれるのがYeomanというツールです。


The web's scaffolding tool for modern webapps | Yeoman


Yeomanはプロジェクト生成ツール「Yo」と依存性管理ツール「Bower」、ビルドツール「Grunt」から構成され、これらを使うことでフロントエンド開発の煩雑さから開放してくれる・・らしいです(普段フロントエンド開発やらないからわからん

実行環境

いつもどおりMacでやります。OSはOS X Yosemite 10.10.1です。
使用する諸々のバージョンは以下の通りです。

名前 バージョン
yo 1.4.7
grunt 0.4.5
grunt-cli 0.1.13
bower 1.4.1
generator-angular 0.11.1

インストール

まずインストールにはnpmが必要なので、Homebrewからnode.jsをインストールします。

$ brew install node
$ npm install -g npm

なお、Yeomanではcompassが必要らしいので、rubyもHomebrewでインストールします。

$ brew install ruby
$ gem update --system
$ gem install compass

以上で準備OKなので、Yeomanをインストールします。ついでにAngularJSのひな型となるgenerator-angularもインストールしておきましょう。

$ npm install -g yo grunt-cli bower
$ npm install -g generator-angular

AngularJSプロジェクトの作成

インストールができたら、早速Yoを使ってプロジェクトのひな形を作成します。

$ mkdir yeoman
$ cd yeoman
$ yo angular
     _-----_
    |       |    .--------------------------.
    |--(o)--|    |    Welcome to Yeoman,    |
   `---------´   |   ladies and gentlemen!  |
    ( _´U`_ )    '--------------------------'
    /___A___\
     |  ~  |
   __'.___.'__
 ´   `  |° ´ Y `

Out of the box I include Bootstrap and some AngularJS recommended modules.

? Would you like to use Sass (with Compass)? Yes
? Would you like to include Bootstrap? Yes
? Would you like to use the Sass version of Bootstrap? Yes
? Which modules would you like to include? (Press <space> to select)
❯◉ angular-animate.js
 ◯ angular-aria.js
 ◉ angular-cookies.js
 ◉ angular-resource.js
 ◯ angular-messages.js
 ◉ angular-route.js
 ◉ angular-sanitize.js
 ◉ angular-touch.js

yo angularすると、例のおじさんが出てくるので、言われるがまま、Sassの使用とかBootstrapの使用とかを設定します。とりあえず全部Yesで、ライブラリは上記の通りデフォルトでインストールします。
選択が終わると、ごちゃごちゃ色々表示されて、色々ダウンロードされたりします。完了すると、yo angularしたディレクトリ配下に色々なファイルやディレクトリが作成されますので確認しておいてください。

静的サーバの起動

さて、プロジェクトが作成されたら、デフォルトでの動作検証をしましょう。
YeomanではGruntを使って、ローカルに静的なサーバを立ち上げることができます。

$ grunt serve

コマンドを実行すると、色々表示された上で、以下のような画面が立ち上がります。

f:id:watass:20150621001923p:plain

一方、grunt serveを実行したコマンドラインはWatchingとなっており、未だに実行中です。これはプロジェクト配下のファイルを変更した際に、変更を即座に検知して、リアルタイムで静的サーバの表示に反映させるためです。
Ctrl+Cでこの状態から抜けることができます。その際にはgrunt serveで立ち上げていたサーバには接続できなくなりますので注意してください。
今後はこの状態のまま、必要なファイルを適宜いじって状況の反映を確認していきます。

生成されたプロジェクトの構成

さて、ここからは自分のアプリを開発するために、プロジェクトで生成されたファイルをいじる必要があるので、まず生成されたファイル群について少し確認します。

基本的にはappディレクトリ配下にメインとなるコンポーネントが格納されます。index.htmlが最初に表示されるものになりますが、実体はその配下のディレクトリ配下のコンテンツが組み込まれており、index.htmlに記載されているのはヘッダやフッタ、AngularJSのディレクティブの記述、各スクリプトの読み込み宣言などになります。詳しく見て行きましょう。

scripts

プロジェクトで使用されるAngularJSのJavaScriptファイル群の置き場です。直下にあるapp.jsはルーティングを司り、index.htmlに組み込むhtmlファイルや使用するコントローラーの宣言をします。controllerディレクトリ配下にはapp.jsで記載されているコントローラーの定義を行うJavaScriptを配置しています。デフォルトではmain.jsとabout.jsがありますので、今回はmain.jsのコントローラー定義を拡張します。

views

index.htmlに組み込まれるhtmlファイル群の置き場です。呼び出しの定義はscriptsディレクトリ配下のapp.jsでされています。デフォルトではmain.htmlとabout.htmlがありますので、今回はmain.htmlを拡張します。

styles

プロジェクトで使用されるCSSファイル群です。ここにCSSをおいて読み込むことで、独自のレイアウトを適用させることができます。今回は特にいじりません。

images

画像ファイル群です。Yeomanの画像がおいてあります。今回は特にいじりません。

main.jsの拡張

デフォルトの設定を確認できたので、本来の目的であるAPIリクエストと非同期の画面更新を実現するために、以下のようにmain.jsを拡張します。

'use strict';

/**
 * @ngdoc function
 * @name yeomanApp.controller:MainCtrl
 * @description
 * # MainCtrl
 * Controller of the yeomanApp
 */
angular.module('yeomanApp')
  .controller('MainCtrl', ['$scope', 'ApiData', function ($scope, ApiData) {
    $scope.Reload = function () {
        ApiData.get().then(function(res){
            $scope.items = res.data;
            $scope.show_loading = false;
        });

        $scope.show_loading = true;
    };

    $scope.Reload();

  }])

  .factory('ApiData', function ($http) {
    return {
        get: function () {
            return $http.get('mock/sample.json')
                .success(function (data, status, header, config) {
                    var time = new Date().getTime();
                    while (new Date().getTime() < time + 1000) {}
                    return data;
                });
            }
    };
  });

APIをリクエストして、データを受け取る機構をファクトリーとして追加実装します。sample.jsonはappディレクトリ配下にmockディレクトリを作り、そこに配置しました。中身については以下の記事で使用しているものと同じものを使っています。1秒のウェイト機構もこちらから拝借しました。ありがとうございます。

qiita.com

コントローラーは$scope内にApiDataのgetメソッドを実行するReloadメソッドを定義します。内容的には上記の記事とほぼ同じですが、関数として実装しているのと、読み込み時に実行できるようにController内で実行するようにしておきます。

main.htmlの拡張

js側の実装ができたので、テンプレートを対応するように編集します。
今回はgrunt serveで立ち上がるYeomanのデフォルト画面で、JSONのデータを取得してくる実装を想定していますので、以下のようにmain.htmlを拡張します。

<div class="jumbotron">
  <h1>'Allo, 'Allo!</h1>
  <p class="lead">
    <img src="images/yeoman.png" alt="I'm Yeoman"><br>
    Always a pleasure scaffolding your apps.
  </p>
  <p><a class="btn btn-lg btn-success" ng-click="Reload()">Reload!<span class="glyphicon glyphicon-ok"></span></a></p>
</div>

<div class="row marketing">
  <div ng-show="show_loading">
    <p>Now Loading...</p>
  </div>
  <li ng-repeat="item in items" ng-hide="show_loading">
    {{ item.id }} - {{ item.name }}
  </li>
</div>

基本的には上記の記事で紹介した仕組みと同様ですが、ボタンの記述をReloadにして、ng-clickでReload関数を指定します。これでボタンクリックによってJSONの再読み込みが非同期にできるようになります。
ちょっとサンプルは用意しにくいのでぜひ自力で試してみてください。

まとめ

  • Yeomanを使えば、AngularJSやBootstrapなどのフロントエンドツール管理が楽になる
  • gruntを使って静的サーバの起動も楽にできる
  • main.jsとmain.htmlを拡張することで、簡単にAPIの非同期画面更新も実装できる

Yeoman楽しい

フロントエンド開発に関しては、正直あんま興味ないかなと思っていましたが、なかなかに楽しい。何より、モダンなそれっぽいUIが作れるとモチベーションにつながりますね。
SassとかBootstrapとかAngularJSとかReact.jsとか最近のフロントエンド事情も熱い感じだなーとはなんとなく眺めていましたので、それらを一括してYeomanでなんとなく触れるのはいいですね。

FuelPHPのRESTコントローラーを使ってAPIの仕組みを実装できれば、ViewにYeomanで作ったAngularJSを組み込むことでそれっぽいアプリが作れそうだなと。
今後はYeomanでFuelPHPの環境に生成したAngularJSのスクリプトを配置するのをやってみたいと思います。

参考

Yeomanのあれこれ - Qiita
# Yeoman導入に参考にさせていただきました。
Yeomanを使ったAngularJSアプリをチームで共同開発して公開するまで - Qiita
# 同様にYeomanの導入やらなにやらの辺りを参考にさせていただきました。
YeomanがジェネってくれるAngularアプリのファイル/ディレクトリ構成メモ - Qiita
# generator-angularで生成されたプロジェクト構成について参考にさせていただきました。
すぐできる AngularJS
# AngularJSのチュートリアルです。ひと通り勉強はここでやりました。
JavaScript - AngularJSでAPIをコールし非同期で画面を更新する - Qiita
# APIと非同期画面更新について一番参考にさせてもらいました。ありがとうございます。