Monaco（Visual Studio Online）でTypeScript + AngularJS

どれも慣れていないので、1から学習。

# 事前準備
Microsoft AzureとVisual Studio Onlineに登録。無料評価版で。

# 新規Webサイトの作成
[このあたりの記事](http://www.atmarkit.co.jp/ait/articles/1312/20/news037.html)を見つつ。Azureの場合、Webサイトは10個までなら無料で作れるらしい。サイトを作成したら、「構成」タブの「VISUAL STUDIO ONLINEでの編集」をオンにして保存。「ダッシュボード」タブの中にある「Visual Studio Onlineでの編集」リンクをクリックするとMonacoの画面が表示される。

# TypeScriptのMonacoへのインストール
コンソールを開いて、コマンドを実行。

`\> npm install typescript`

# AngularJSのMonacoへのインストール
先にbowerを入れる。

`\> npm install bower`

その後、「bower.json」のファイルをルートディレクトリに作成。内容は[チュートリアルのGitHub](https://github.com/angular/angular-phonecat)にあるbower.jsonのファイルと同じ中身にした。このファイルが作れたら、以下のコマンドを実行。

`\> bower install`

# DefinitelyTypedのファイルの用意
TypeScriptでAngularJSのコードを書いていく上で必要なDefinitelyTypedのファイルを[DefinitelyTypedのGitHub](https://github.com/borisyankov/DefinitelyTyped)からangular.d.tsを持ってきた。あと、このファイルは、jQueryに依存しているので、jQueryのDefinitelyTypedのファイル（jquery.d.ts）も持ってきた。

# AngularJS チュートリアル Step2まで
[公式のチュートリアルページ](https://docs.angularjs.org/tutorial)のStep2までを、とりあえず。できれば機能ごとにソースを分けてコードを書きたかったため、試行錯誤の結果、以下のようなフォルダ構成に。（ファイル名やコードの内容などなどを、個人的な好みの理由で、チュートリアルページのものとは違う形になってしまったものもある点、ご了承の程を。）

![monaco01.png](https://qiita-image-store.s3.amazonaws.com/0/21867/aa9265c5-4bf5-799e-fe29-b75e38bd9615.png)

コーディングにあたっては、以下のあたりの記事を参考にさせてもらった。

* [AngularJSをTypeScriptで書くときのあれこれ(Qiita)](http://qiita.com/zoetro/items/1aefa189cb54169f2cee)
* [お前のAngular.jsはもうMVCではない。と言われないためのTutorial(Qiita)](http://qiita.com/icoxfog417/items/2ac773c33a8b34288551)
* [TypeScriptで書くAngularJSのMVC(Qiita)](http://qiita.com/armorik83/items/0778d757c46e953f3fdf)
* [TypeScript & AngularJS todomvc](https://github.com/tastejs/todomvc/tree/gh-pages/labs/architecture-examples/typescript-angular)

以下、各tsファイルとHTMLファイルの内容。

```ts:_all.ts
/// <reference path='libs/jquery/jquery.d.ts' />
/// <reference path='libs/angularjs/angular.d.ts' />
/// <reference path='models/PhoneItem.ts' />
/// <reference path='scopes/PhonecatScope.ts' />
/// <reference path='controllers/PhoneListController.ts' />
/// <reference path='./PhonecatApp.ts' />
```

```ts:PhoneItem.ts
/// <reference path='../_all.ts' />
module Phonecats {
	export class PhoneItem {
		private _name;
		private _snippet;
		
		get name() {
			return this._name;
		}
		set name(newName) {
			this._name = newName;
		}
		get snippet() {
			return this._snippet;
		}
		set snippet(newSnippet) {
			this._snippet = newSnippet;
		}
		
		constructor(newName, newSnippet) {
			this._name = newName;
			this._snippet = newSnippet;
		}
	}
}
```

```ts:PhonecatScope.ts
/// <reference path="../_all.ts" />
module Phonecats {
	export interface PhonecatScope extends ng.IScope {
		phones:Array<PhoneItem>;
	}
}
```

```ts:PhoneListController.ts
/// <reference path="../_all.ts" />
module Phonecats {
	export class PhoneListController {
		private scope:PhonecatScope;
		constructor($scope:PhonecatScope) {
			this.scope = $scope;
		}
	}
}
```

```ts:PhonecatApp.ts
/// <reference path="./_all.ts" />
module Phonecats {
	export interface PhonecatApp extends ng.IModule {}
	
	var phonecatApp:PhonecatApp = angular.module("phonecatApp", []);
	phonecatApp.controller("PhoneListController", ($scope:PhonecatScope) => {
		var phoneJsonData:string = '['
			+ '{"name": "Nexus2 S","snippet": "Fast just got faster with Nexus S."},'
			+ '{"name": "Motorola3 XOOM™ with Wi-Fi", "snippet": "The Next, Next Generation tablet."},'
			+ '{"name": "MOTOROLA4 XOOM™", "snippet": "The Next, Next Generation tablet."}'
 			+ ']';
		var parsePhonesData:Array<any> = JSON.parse(phoneJsonData);
		
		var phones:Array<PhoneItem> = [];
		parsePhonesData.forEach((phone) => {
			phones.push(new PhoneItem(phone.name, phone.snippet, phone.age));
		});

		$scope.phones = phones;
	});
}
```

```html:test.html
<!doctype html>
<html lang="ja" ng-app="phonecatApp">
<head>
  <meta charset="utf-8">
  <title>My HTML File</title>
  <link rel="stylesheet" href="bower_components/bootstrap/dist/css/bootstrap.css">
  <link rel="stylesheet" href="css/app.css">
  <script src="bower_components/angular/angular.js"></script>
  <script src="js/PhonecatApp.js"></script>
  <script src="js/models/PhoneItem.js"></script>
  <script src="js/scopes/PhonecatScope.js"></script>
  <script src="js/controllers/PhoneListController.js"></script>
</head>
<body ng-controller="PhoneListController">

  <ul>
    <li ng-repeat="phone in phones">      
      {{phone.name}}
      <p>{{phone.snippet}}</p>
    </li>
  </ul>

</body>
</html>
```

# jsファイルにコンパイル
PhonecatApp.tsファイルをコンパイルするコマンドのみで他のtsファイルもコンパイルされた。

`\> tsc --module commonjs --target "ES5" js/PhonecatApp.ts`

# ブラウザから動作確認
Monacoの「Browse Web Site」からサイトを開き、「(サイトURL)/test.html」を開く。チュートリアルの内容と同じ表示結果となっていることを確認した。

# これから調べたいこと、その他
* Unit Testどうしよう
* [このjsファイル](https://github.com/tastejs/todomvc/blob/gh-pages/labs/architecture-examples/typescript-angular/js/Application.js)みたいに、複数のtsファイルのコンパイル結果をひとつのjsファイルにまとめる形でのコンパイル方法
* AngularJSチュートリアルのStep3以降の実施。（こうしてみようと思ってやってみたことが裏目に出てしまって、コードを書き換えないと次のチュートリアルが出来ない、とかあるかも…。）