Angular 2入門：NgModelに触れてみる

【20160819更新】rc.5対応した記事を書きました。[Angular 2入門：NgModelに触れてみる [rc.5対応]](http://qiita.com/shinsukeimai/items/af159944967424260b0e)
この記事で書かれている内容は古いため参考にされないようご注意ください。

---

おはようございます。今井です。
最近は、[ng-kyoto](http://ng-kyoto.github.io/)というAngularユーザーコミュニティでオーガナイザーをさせていただいております。Angular 2というこれまでのAngular JSとは全く異なる（！？）フレームワークがそろそろβ版になるということで、初めて触れる次第です。

私が初めてAngular JSと触れた時に一番印象的だったのは双方向バインディングだったような気がします。その双方向バインディングがAngular 2でどうなったのかを見てみたいと思います。

注意：この記事では、Angular 1.xをAngular JS。Angular 2.xをAngular 2と呼称します。

#前提
- すでにAngularJSにある程度触れられている方を対象とします。
- [@armorik83](http://qiita.com/armorik83)氏の[記事](http://qiita.com/armorik83/items/519cbc94459a87a4fbba)を読まれた前提で話を進めていきます。
- この記事時点でのAngular2のバージョンは2.0.0-alpha.47です。

#公式サイト
- https://angular.io/
- https://github.com/angular/angular

#ModelからViewへ
MVCモデルでいうModelからViewへ値を反映させてみます。

```index.ts
import "reflect-metadata";
import "zone.js";
import {bootstrap, Component} from "angular2/angular2";

@Component({
    selector: "my-app",
    template: `
        <h1>{{title}}</h1>
    `
})
class MyApp {
  public title = "Hello";
}

bootstrap(MyApp);
```

[@armorik83の記事](http://qiita.com/armorik83/items/519cbc94459a87a4fbba)をやってみてからだとすごく簡単ですね。
`import`はおまじないと考えて、必要なAPIを取得していきます。初回起動時に必要な`bootstrap`、コンポーネント定義に必要な`Component`を引っ張ってきて利用します。`@Component`にて、Angular JSでのDirectiveに似たものを記述していきます。`Decorator`というようです。`Component`で利用する`Class`、`HTML template`を記述していきます。そして、最終的なエントリーポイントである`bootstrap`を記述します。

#ViewからModelへ
ViewからModelへということで、input要素で得た値をバインディングしてみましょう。 Angular JSでは、[`ng-model`](https://docs.angularjs.org/api/ng/directive/ngModel)というDirectiveを利用していたかと思いますが、Angular 2では[`NgModel`](https://angular.io/docs/ts/latest/api/common/NgModel-directive.html)というDirectiveが存在します。


```index.ts
import "reflect-metadata";
import "zone.js";
import {bootstrap, Component, FORM_DIRECTIVES} from "angular2/angular2";

@Component({
    selector: "my-app",
    directives: [FORM_DIRECTIVES],
    template: `
        <h1>{{title}}</h1>
        <input type='text' [(ng-model)]="title">
    `
})
class MyApp {
  title: string = "Hello World!";
}

bootstrap(MyApp);
```

TypeScriptには慣れていかないとダメですが、簡単ですね。`[(...)]`という記述が特徴的ですね。[bindon-ng-model](https://angular.io/docs/ts/latest/guide/template-syntax.html#ng-model)という書き方もありますが、`[(...)]`の方が奨励されていますね。
`[...]`がインプットプロバティ、`(...)`がアウトプットプロバティを意味しています。インプットプロバティは、そこに入れる値、アウトプットプロバティは、値が変化したときに動作することを意味していると考えて良いでしょう。
試しに、`(...)`を抜いてみましょう。

```index.ts
import "reflect-metadata";
import "zone.js";
import {bootstrap, Component, FORM_DIRECTIVES} from "angular2/angular2";

@Component({
    selector: "my-app",
    directives: [FORM_DIRECTIVES],
    template: `
        <h1>{{title}}</h1>
        <input type='text' [ng-model]="title">
    `
})
class MyApp {
  title: string = "Hello World!";
}

bootstrap(MyApp);
```

値がバインディングされなくなったかと思います。では、`ng-model-change`を付け加えて変更時に値をバインディングさせましょう。

```indes.ts
import "reflect-metadata";
import "zone.js";
import {bootstrap, Component, FORM_DIRECTIVES} from "angular2/angular2";

@Component({
    selector: "my-app",
    directives: [FORM_DIRECTIVES],
    template: `
        <h1>{{title}}</h1>
        <input type='text' [ng-model]="title" (ng-model-change)="title=$event">
    `
})
class MyApp {
  title: string = "Hello World!";
}

bootstrap(MyApp);
```

このように、`[(ng-model)]="title"`は`[ng-model]="title" (ng-model-change)="title=$event"`に置き換え可能な訳ですね。ちなみにAngular 2に詳しい人によると、 **Angular 2では双方向バインディングというより、単方向のバインディング設計** になっている模様。Inputs、Outputsという表現からもその思想がうかがえますね。でもまだAlpha版なので、Breaking Changeがあるかもしれないのでご注意くださいね。

#最後に
いかがでしたか？私も今回初めてAngular 2に触れてみましたが、Angular JSより記述しやすくなったなと感じています。みなさんもAngular 2を今から触れてみては！？
[書いたコード](https://github.com/shinsukeimai/advent-angular2)貼っときます。
レビューしてくれたng-kyotoの皆さんThanks!!
明日は@rdlaboさんです。