yutaponのブログ

javascript界隈の興味あるネタを備忘録的に残しておく場所

AngularJSを触ってみた感想

AngularJSってどんなものかなとオライリーのAngularJS本を3章まで読み進めたのでその感想を。

AngularJSアプリケーション開発ガイド

AngularJSアプリケーション開発ガイド


この本の章構成は

  • 1章 イントロダクション
  • 2章 AngularJSアプリケーションの構造
  • 3章 AngularJSアプリケーションの開発
  • 4章 AngularJSアプリケーションの内部構造
  • 5章 サーバとの通信
  • 6章 ディレクティブ
  • 7章 その他の便利な機能
  • 8章 レシピ集

となっており、2章でAngularJSってどんなものか、
大体網羅されてるのでそれを読んだ感想になります。


AngularJSとは

AngularJSはフロントエンド用のMVCフレームワークです。
(公式にはMVWフレームワークと書いてますね)
AngularJS — Superheroic JavaScript MVW Framework


本を読んでみて、特徴だと思ったことは

といった感じでした。


AngularJSの使い方

手っ取り早くAngularJSを動かすにはYoemanを使うといいです。

$ cd path/to/workspace # 作業ディレクトリに移動
$ mkdir appName        # applicationの名前のディレクトリ作成
$ cd appName           # プロジェクトに移動
$ npm install -g yo    # yoemanをインストール
..
$ npm install generator-angular  # ジェネレータ入れる(globalに入れても良い)
..
$ yo angular # プロジェクトのひな形作成
..

# sass, compassが入ってなければ入れる
$ sudo gem install sass compass
..
$ rbenv rehash # rbenv使ってる場合

# AngularJS動かす
$ grunt server
..
# ブラウザにひな形が表示される
# ソースがwatchされてて変更のたびに自動リロードされる

 
こんなページが表示されます。

f:id:sskyu:20140420195342p:plain

右上にHome、About、Contactというボタンがありますが、
押しても何もおきません。たぶん実装してねってことなんでしょう。


それでは生成されたソースを見ていきます。


Angular本体の読み込みやアプリケーションコードの読み込み

appDir/index.htmlでAngular本体の読み込み、アプリケーションの読み込みが行なわれています。
注目する部分を抜き出してみました。

<body ng-app="angular01App"><!-- ng-appディレクティブ -->
    <div class="container" ng-view=""></div><!-- ng-viewディレクティブ -->

    <!-- いろいろあって -->

    <script src="bower_components/jquery/dist/jquery.js"></script>
    <script src="bower_components/angular/angular.js"></script>

    <!-- いろいろ読み込んで -->

    <script src="scripts/app.js"></script><!-- config的なファイル -->
    <script src="scripts/controllers/main.js"></script><!-- アプリケーションコード -->

 

ng-appディレクティブ

ng-appディレクトリをタグに含めることで、そのタグ内はAngularJSで管理するって意味になります。
値に"angular01App"が渡されていますが、Module名を渡してます。
AngularJSアプリケーション起動時に実行するModule名を渡します。

ng-viewディレクティブ

オライリー本に出てきてない気がしますが、公式ドキュメントに載ってました。
https://docs.angularjs.org/api/ngRoute/directive/ngView

要は$routeによって監視してるURLが変更されたら、ng-viewディレクティブが付いてる要素の中にテンプレートがまるっと流し込まれるそうな。


app.js (config)

app.jsの中身はこんな感じ。
なんとなく、Routingの設定がされてるのがわかるかと。

// @file app.js <app/scripts>

'use strict';

angular
  .module('angular01App', [  // 'angular01App'というモジュールを作る
    'ngCookies',   // 配列でモジュールを読み込んでいる (include的な記述)
    'ngResource',
    'ngSanitize',
    'ngRoute'
  ])
  .config(function ($routeProvider) {
    $routeProvider
      .when('/', {
        templateUrl: 'views/main.html',
        controller: 'MainCtrl'
      })
      .otherwise({
        redirectTo: '/'
      });
  });

 
routeの設定はURLと、そのURLで表示するVとCの組み合わせを与えればいいらしい。
もっと詳しい情報はこちら。
https://docs.angularjs.org/api/ngRoute/provider/$routeProvider
 

Controller

appDir/scripts/controllers/main.jsに、app.jsで指定されていたMainCtrlの実体があります。

// @file main.js <app/scripts/controllers>

'use strict';

angular.module('angular01App')
  .controller('MainCtrl', function ($scope) {
    $scope.awesomeThings = [
      'HTML5 Boilerplate',
      'AngularJS',
      'Karma'
    ];
  });

 

$scope

基本、$が先頭についた変数はAngularJS組み込みの変数です。
$scopeはコントローラが管理する要素と共有する名前空間みたいなものです。
$scopeに変数を追加して、それをテンプレ側で表示するって使い方が基本です。


Backbone.js慣れしてると、先頭に$付けた変数はjQueryオブジェクトをキャッシュした変数と思いがちですが、AngularJSではjQuery使ってDOMの操作をすることはないようです。
むしろタブーになってるそうな。
AngularJSのお作法に則り、そういう状況になるようであれば別の道を探したほうが良さそうです。


View

appDir/views/main.htmlがViewファイルになります。

<div class="header">
  <ul class="nav nav-pills pull-right">
    <li class="active"><a ng-href="#">Home</a></li>
    <li><a ng-href="#">About</a></li>
    <li><a ng-href="#">Contact</a></li>
  </ul>
  <h3 class="text-muted">angular01</h3>
</div>

<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-href="#">Splendid!<span class="glyphicon glyphicon-ok"></span></a></p>
</div>

<!-- 以下略 -->

 
scaffoldで作成したテンプレだとあまり面白くないですね。
ng-xxとついてるディレクティブがところどころに見られます。

controllerで定義されてたawesomeThingsが参照されてないので、
テンプレに追記して表示させてみます。

<!-- 適当なところに追記する -->
<div ng-controller="MainCtrl">
  <div ng-repeat="thing in awesomeThings">
    <input type="text" value="{{thing}}"><span>{{thing}}</span>
  </div>
</div>

 
ng-controllerの値にMainCtrlを指定したので、
この要素以下ではMainCtrlのスコープが共有されることになります。


ng-repeatは for in みたいな使い方ができます。
でもこれ、Handlebars風に書けたほうがきれいに書けると思いました。
なぜfor in風にしたんだろ。


AngularJSの所感

初心者の感想としては、View側にロジックを寄せないように書かないと大変そうと思いました。

Backbone.jsでもそうですが、テンプレでロジックを頑張り過ぎると見通しが悪くなります。


また、双方向データバインディングを試そうと$watchを試してみましたが、
Arrayへの$watchでハマり調査中です。

Modelも試していないし、もっとAngularJS本を読んで出直してきます。


良さそうだと思ったところは、Angularでブラウザ間の差異を吸収してくれるところとか、CORS, CSRF対策などをフレームワーク側で用意してくれているところ。

使いこなせば楽をできそうだけど、学習コストは高そう。
(Backbone.jsもそれなりに学習コストあるけど・・)

ココらへんも一緒に読むと理解が捗りそう。
AngularJS 1.2 日本語リファレンス | js STUDIO
AngularJS Ninja



おわりに

Angularのことを全然わかってない状態から、こういうものかってくらいには学べました。
Backbone.jsと対比しながら読むとわかりやすかった。

より詳しい情報は4章以降に載っているみたいなので、
引き続き読み進めていきます。


何か作りながらやったほうが覚えがいいので、何かのシステムの管理画面をAngularJSで作るとかやってみたい。