pirosikick's diary

君のハートにunshift

Angular.jsとTypeScript

Angular.jsでaltJSを使う場合、CoffeeScriptが一般的(たぶん)だが、TypeScriptはあんまり聞かない。TypeScriptの方が好きな自分としてはどうにかならんかねとずっと考えていて、こうやったらいいんじゃないかというのを思いついたのでメモ。

controller定義の基本

Angular.jsでcontrollerを定義する場合、だいたいはangular.module.controllerの第1引数にcontroller名、第2引数にcontrollerのコンストラクタ関数を渡す。

var app = angular.module('app', []);

// 'MainCtrl'という名前のcontrollerを定義
app.controller('MainCtrl', function ($scope) {

});

このままだとminiyした時にinjectがうまくいかないので、第2引数に配列を渡して明示的にinjectを定義するか、コンストラクタ関数に$injectを定義する方法がある。

// 第2引数に配列を渡すケース
app.controller('MainCtrl', ['$scope', function ($scope) {
  // do something
}]);
// $injectを定義するケース

function MainCtrl ($scope) {
  // do something
}

MainCtrl.$inject = ['$scope'];

app.controller('MainCtrl', MainCtrl);

たぶんあんまり知られていないcontrollerの定義方法

ドキュメントには多分載ってないと思うのですが、angular.module.controllerにハッシュオブジェクトを渡すことができて、keyにcontroller名、valueにcontrollerのコンストラクタ関数という感じで一気に複数のcontrollerを定義できる

// MainCtrlとSubCtrlを一気に定義する
app.controller({
  MainCtrl: function ($scope) { /* do something */ },
  SubCtrl: function ($scope) { /* do something */ }
})

これを活かして、app.controllersみたいな感じでNamespaceを作ってそこにcontrollerを定義して、Namescpaceごとangular.module.controllerに渡してしまうのが楽なのではないかと思うのです。

TypeScriptの場合、moduleを使えば簡単にNamespaceが定義できる。

// controllers.ts
// 今回は1つのファイルに2つのcontrollerを定義
// 実際は分けてもいいかと思います。

module app.controllers {

  // MainCtrl
  export class MainCtrl {
    // injectionを明示的に定義
    static $inject = ['$scope'];

    constructor ($scope) {
      // do something
    };
  }

  // SubCtrl
  export class SubCtrl {
    // injectionを明示的に定義
    static $inject = ['$scope'];

    constructor ($scope) {
      // do something
    };
  }
}
// app.js

angular.module('app', [])
  // controllerを一気に定義
  .controller(app.controllers);

controllerだけでなくdirectiveservice等もハッシュオブジェクトを渡して定義できるので、応用できるはず。