angularJSで遊んでみる

こんばんは、最近風邪気味でちょっぴり辛い思いをしているsouth37です。
寒い格好は良く無いですね!

今日は、前回ちょろっと紹介したangularJSを使って適当なアプリを作って遊んでみたいと思います。何を作るかはノープランですが、何とかなるでしょう。

yeomanでひな形を作る

さて、まずはアプリのひな形を作ります。その為の便利なツールが、yeomanという奴です。yeomanはgoogle製の総合開発ツール群で、コードジェネレータのyo, タスクランナーのgrunt, パッケージマネージャのbowerの3つのツールから構成されます。gruntとbowerはちょろっと名前を出した事がありますね。yoはrailsのscaffoldみたいなやつで*1、yoコマンドを打って例えばangular-generatorを選ぶと、angularJSを使ったアプリのひな形コードが生成されます。ついでにGruntfile.jsやbower.jsonも生成され、さらにbower installで必要なjsライブラリのダウンロードまで行われます。至れり尽くせりですね!

で、このひな形を元にサンプルとしてメモアプリを作ってみました。といっても、以前backbone.jsを勉強した時に書いたものとほぼ同じような奴です。

'use strict';

angular.module('practiceApp', [
  'ngCookies',
  'ngSanitize',
  'ngRoute'
])
  .config(function ($routeProvider) {
    $routeProvider
      .when('/', {
        templateUrl: 'views/main.html',
        controller: 'MainCtrl'
      })
      .otherwise({
        redirectTo: '/'
      });
  });

yoによって生成されたapp.jsファイルの中身がこれです。angular.moduleでpracticeAppモジュールを定義しています。また、configメソッドで$routeProviderサービスを使ってroutingの設定をしています。上記のコードでは、/にアクセスされた時はviews/main.htmlをcontrollerをMainCtrlとしてレンダリングし、それ以外のUrlにアクセスされた場合には/へリダイレクトされます。

htmlファイルには、

<body ng-app="practiceApp">
  <div class="container" ng-view=""></div>
</body>

のような記述があり、ng-view属性を持つdivタグ部分でテンプレートファイルがレンダリングされます。angularJSにおけるテンプレートファイルはhtmlで、

<div class="header">
  <h2 class="text-muted"><a href="#">Memo Application</a></h2>
</div>

<h3>New Memo</h3>
<div class="form-group">
  <input ng-model="title" type="text" name="title" class="form-control" placeholder="Title" />
</div>
<div class="form-group">
  <textarea ng-model="content" rows="3" name="content" class="form-control" placeholder="Content"></textarea>
</div>
<div ng-click="add()" class="btn btn-primary">Add</div>

<h3>Memos</h3>
<div class="panel panel-default" ng-repeat="memo in memos">
  <div class="panel-heading">
    <h4 class="panel-title">{{memo.title}}</h4>
  </div>
  <div class="panel-body">
    <p>{{memo.content}}</p>
    <div href="#" ng-click="remove($index)" class="btn btn-danger btn-sm">delete</div>
  </div>
</div>

<div class="footer">
  <p>from south37</p>
</div>

こんな感じになっています。ng-modelやng-repeatのようなderivertiveを使っているのが特徴的ですね。ng-repeat中で出てくる$indexもポイントで、$indexには配列memos中の選択した要素のインデックスが入っているため、要素の削除等を簡単に行う事が出来ます。

MainCtrlコントローラを定義しているjsファイルの中身は、

'use strict';

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

    var Memo = function (title, content) {
      this.title = title;
      this.content = content;
    };

    $scope.memos = [new Memo('Sample', 'This is sample memo')];

    $scope.add = function () {
      $scope.memos.push(new Memo($scope.title, $scope.content));
      $scope.title = '';
      $scope.content = '';
    };

    $scope.remove = function (i) {
      $scope.memos.splice(i, 1);
    };
  });

こんな感じになっています。addとremoveメソッドを定義して、使えるようにしています。

これで一通り動くはずです。ぜひ試してみてください。

*1:というか実際かなり影響を受けているらしい