AngularJSとRequireJSを合わせて使ってみた


モジュール単位でファイルに分けたいかなーと思ったので、
AngularJS本家のチュートリアルのphonecatAppを題材にして、
AngularJS + RequireJS | StarterSquadを参考にちょっとアレンジ。


結果のソースはこちら
単体テストの実行と結合したソースをproduction.htmlで見れるところまで確認。

アプリの定義


phonecatApp.controllersにはPhoneListCtrlとPhoneDetailCtrlが入ってる。
phonecatApp.filtersにはcheckmark、
phonecatApp.servicesにはPhoneがそれぞれ入ってる。

app/assets/js/app.js

define([
  'angular',
  'angularRoute',
  'angularResource',
  './services/Phone',
  './filters/checkmark',
  './controllers/PhoneListCtrl',
  './controllers/PhoneDetailCtrl'
], function(angular) {

  'use strict';

  var phonecatApp = angular.module('phonecatApp', [
    'ngRoute',
    'phonecatApp.controllers',
    'phonecatApp.filters',
    'phonecatApp.services'
  ]);
  phonecatApp.config([
    '$routeProvider',
    function($routeProvider) {
      $routeProvider.
        when('/phones', {
        templateUrl: 'assets/js/templates/phone-list.html',
        controller: 'PhoneListCtrl'
      }).
        when('/phones/:phoneId', {
        templateUrl: 'assets/js/templates/phone-detail.html',
        controller: 'PhoneDetailCtrl'
      }).
        otherwise({
        redirectTo: '/phones'
      });
    }
  ]);
  return phonecatApp;
});

モジュール定義(例:コントローラ)


依存関係で読み込んでいるmodule(app/assets/js/controllers/module.js)がポイントになる。

app/assets/js/controllers/PhoneListCtrl.js

define([
  './module',
  '../services/Phone'
], function(controllers) {

  'use strict';

  return controllers.controller('PhoneListCtrl', [
    '$scope',
    'Phone',
    function($scope, Phone) {
      $scope.phones = Phone.query();
      $scope.orderProp = 'age';
    }
  ]);
});


moduleでphonecatApp.controllersを定義してコントローラを登録させる。
servicesとかも似たような感じで各まとまりでmodule作ってそこに登録させる。

app/assets/js/controllers/module.js

define([
  'angular',
], function(ng) {
  'use strict';
  return ng.module('phonecatApp.controllers', []);
});

アプリの起動


ng-appディレクティブだと間に合わないので、angular.bootstrapを使って手動でphonecatAppを実行する。

app/assets/js/bootstrap.js

require([
  'angular',
  'app'
], function(ng) {
  'use strict';

  ng.bootstrap(document, ['phonecatApp']);
});

感想


define、requireとangular.module両方で依存定義する必要があるので、ちょっと微妙。