AngularJSをとりあえず触ってみたい人向けの記事です。 面倒なので今回はYEOMANを使います。

準備するもの

YEOMANとAngularJS用のジェネレーター

npm install -g yo
npm install -g generator-angular

Compass(generator-angularが使っている)

gem install compass

AngularJSのひな形を作成

適当にディレクトリを作って、そこで作業します。

YEOMANを使ってセットアップ(結構時間かかります)

yo angular
[?] Would you like to include Twitter Bootstrap? Yes
[?] Would you like to use the SCSS version of Twitter Bootstrap with the Compass CSS Authoring Framework? Yes
[?] Which modules would you like to include? [Enter]
 ⬢ angular-resource.js
 ⬢ angular-cookies.js
 ⬢ angular-sanitize.js
 ⬢ angular-route.js

さっそく動かしてみる

セットアップが完了したら表示してみます。

grunt serve

image

表示されました。

補足 > Mac(OS X Mavericks)でnode.jsのバージョンが0.10.17の時にgrunt watchタスクがbus errorで動かなかったので、その時はnode.jsをアップデートしたら動くかもしれません。 > 私は0.10.22にアップデートして直りました。

この雛形では、ビューの読み込みしか行っていないので少し編集してAngularJSの部分に触れてみようと思います。

AngularJSのバインディング(Hello World)

なぜこのファイルなのかは後々ルーティングの時に説明するので、とりあえずいろいろ編集してみます。

<!-- app/views/main.html -->
<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">angular sample</h3>
</div>
<div class="jumbotron">
  <p>Hello {{ world }}!</p> <!-- ここを追記 -->
</div>

このままではworldは空っぽなのでコントローラーから値を設定します。

// app/scripts/controllers/main.js
'use strict';

angular.module('angularSampleApp') // モジュール名はディレクトリ名によって変わるので注意
  .controller('MainCtrl', function ($scope) {

    $scope.world = 'Angular'; // ここを追記

  });

これでHello Angular!と表示されるはずです。

image

なんとなくAngularJSの変数が分かると思います。

AngularJSのバインディング ~ 配列編

配列の表示も簡単なのでついでにやります。 明らかにAngularJSっぽいng-initng-repeatが出てきますが、今は こう書けばこう動くんだー 程度の認識でよいです。

<!-- app/views/main.html -->
<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">angular sample</h3>
</div>

<div class="jumbotron">
  <p>Hello {{ world }}!</p>

  <!-- この下の部分を追記 -->
  <p ng-init="frameworks = ['Backbone.js', 'Ember.js', 'Knockout.js']">
    <h3>{{ frameworks.length }} frameworks</h3>
    <ul>
      <li ng-repeat="f in frameworks">{{f}}</li>
    </ul>
  </p>
</div>
  • ngInitで変数の初期化 > コントローラー内で $scope.frameworks = ['Backbone.js', 'Ember.js', 'Knockout.js'];と書くのと同義です。

  • ngRpeatで変数をループしながらレンダリング

リストがちゃんと表示されていればOKです。

image

ここで1つ気づくのが {{ frameworks.length }} の部分です。 {{}}の中身は変数名から変数を取得するだけではなく、AngularJSによってコンパイルされます。

なので {{ frameworks.length * 3 }} のように計算させたり、{{ frameworks.join(',') }}のようにメソッドをコールする事も可能です。

次はリアルタイムに変更されるパターンをやってみます。

ng-model ディレクティブ

AngularJSには処理や、DOMをひとまとめにしておく ディレクティブ(Directive) という仕組みがあります。

その一つに、入力項目とAngularの変数をバインドさせるngModelというディレクティブがあります。 > AngularJSのバインディング ~ 配列編 で使用している ngInit, ngRpeat もディレクティブです。

<!-- app/views/main.html -->
<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>

<div class="jumbotron">
  <p><input type="text" ng-model="world"></p> <!-- この行を追加 -->
  <p>Hello {{ world }}!</p>

  <p ng-init="frameworks = ['Backbone.js', 'Ember.js', 'Knockout.js']">
    <h3>{{ frameworks.length }} frameworks</h3>
    <ul>
      <li ng-repeat="f in frameworks">{{f}}</li>
    </ul>
  </p>
</div>

たったこれだけでリアルタイムにビューに入力値が反映されるようになります。 すばらしいですねー

image

UIイベントとの連携

  • ボタンを押した時に処理を実行
  • 処理結果をビューに反映

今からこの辺りを触ります。

まずボタンを追加

<!-- app/views/main.html -->
<p>
  <input type="text" ng-model="world">
  <span ng-click="addFramework(world)" class="btn btn-primary">Add</span><!-- この行を追加 -->
</p>
<p>Hello {{ world }}!</p>

<p ng-init="frameworks = ['Backbone.js', 'Ember.js', 'Knockout.js']">
  <h3>{{ frameworks.length }} frameworks</h3>
  <ul>
    <li ng-repeat="f in frameworks">{{f}}</li>
  </ul>
</p>

ng-click=”addFramework(world)” に対応する処理をコントローラーに追加

// app/scripts/controllers/main.js
'use strict';

angular.module('angularSampleApp')
  .controller('MainCtrl', function ($scope) {

     $scope.world = 'Angular';

     // この部分を追加
    $scope.addFramework = function (text) {
      $scope.frameworks.push(text);
      $scope.world = '';
    };

  });

書いた処理は以下だけ

  • 渡されたテキストを配列に追加
  • フォームにバインドされたテキストを空にする

補足 $scope.frameworks.push($scope.world) と書けますが、今回は引数を受け取る事ができますという意味であえてこう書いてます。

ビューに結果を反映させるのは、変数に変更を加えればあとはAngularJSがうまい事やってくれるので特に気にしなくてもよいです。

image

これで動作するようになったと思います。

触りの部分は以上です