Angularでのフォーム作成

#フォームとは
- フォームタグで囲われ、input、selectなどを使ってデータを生成しサーバーに送信するもの
- Angularでは容易に実装できるAPIが用意されている
- Angularでフォームを利用するためにはFormsModuleをインポートする
- FormsModuleは「テンプレート駆動フォーム」と呼ばれる形式のフォームを実装するためのモジュール

#フォームの作成
app.module.tsを下記のように実装

```
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import {FormsModule} from '@angular/forms';

import { AppComponent } from './app.component';
import { EmployeeComponent } from './employee/employee.component';

@NgModule({
  declarations: [
    AppComponent,
    EmployeeComponent
  ],
  imports: [
    BrowserModule,
    FormsModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }
```

#格納モデルの作成
- 登録するデータを格納するモデルを作成
- ユーザーがフォームにデータを入力すると、変更が検知されてモデルのインスタンスが更新される
- 従業員情報として、id、名前、電話番号、部署、メールアドレスを登録するフォームを想定
- 以下のクラスをapp.module.tsに追記

```
export class EmployeeModel{
  constructor(
    public id: number,
    public name: string,
    public phone: string,
    public department: string,
    public email?: string
  ){}
}
```

#表示コンポーネントの作成・テンプレート駆動フォームの組み立て
- 以下のコマンドでコンポーネントを作成する

```
$ng g component employee
```
- まずは名前の入力フォームを作成する
- employee.component.htmlを以下のように実装する

```
<div class="container">
  <h1>社員登録</h1>
  <form>
    <div>
      <label>名前</label>
      <div>
        <input placeholder="名前" type="text" id="name" required> 
      </div>
    </div>
    <button type="submit">Submit</button>
  </form>
</div>
```
- 画面は以下の通り
- もちろんこの状況では普通に記述したhtmlが表示されているだけ
<img width="1128" alt="name.png" src="https://qiita-image-store.s3.amazonaws.com/0/269592/ad34595a-89da-aaac-c042-e9672f8381d1.png">


#フォームの準備
- ここからAngularの恩恵を受けます
- 部署を選択できるプルダウンを作成
- employee.component.ts内のEmployeeComponentにプルダウンに表示させたい内容を追記

```
public departments: string[] =[
    'Designer', 'Develop', 'Marketing'
  ];
```
- 続いてemployee.component.htmlに下記を追記

```
   <div>
      <label>部署</label>
      <div>
        <select id="department" placeholder="部署" required>
          <option *ngFor="let department of departments" [value]="department">
               {{department}}</option>
        </select>
      </div>
    </div>
```
- 通常のhtmlと同様に、プルダウンを作成する場合にはselectタグ、optionタグを記述する
- optionタグ内の*ngForで繰り返し表示させたい要素を指定
 - ここではemployee.component.tsで指定した"departments"という変数を呼び出している
- 表示名を変数で指定する場合は{{}}でくくる
- 画面は以下の通り
<img width="1128" alt="pulldown.png" src="https://qiita-image-store.s3.amazonaws.com/0/269592/3268c69b-af5e-cca4-9751-837d0a5a2fb2.png">


#双方向データバインディング
- ここまでは表示の実装のみであり、選択した値が受け渡されることはない
- 選択を反映させるために、双方向データバインディングを利用する
- 値を格納するモデルとして、employee.component.tsに以下の変数を初期値と共に記述する

```
public model: EmployeeModel
   = new EmployeeModel(12, 'Angular', '060-1234-5678', this.departments[1]);
```
- [(ngModel)]を利用することで、データの変更を受け渡すことができる
- これはフロントエンド・バックエンドのどちらからも値を受け渡すことができる
- employee.component.htmlを以下の通り実装

```
<div class="container">
  <h1>社員登録</h1>
  <form>
    <div>
      <label>名前</label>
      <div>
        <input placeholder="名前" type="text" id="name" name="name" minlength="4" required
        [(ngModel)]="model.name"> 
      </div>
    </div>
    <div>
      <label>部署</label>
      <div>
        <select id="department" placeholder="部署" name="department" required
        [(ngModel)]="model.department">
          <option *ngFor="let department of departments" [value]="department">{{department}}</option>
        </select>
      </div>
    </div>
    <div>
      <div class="full-width">
        <label>電話番号</label>
        <div>
          <input placeholder="電話番号" type="text" id="phone" name="phone" required
          [(ngModel)]=model.phone>
        </div>
      </div>
    </div>
    <div class="full-width">
      <label>メールアドレス</label>
    </div>
    <div>
      <input placeholder="メールアドレス" type="text" id="email" name="email" [(ngModel)]="model.email">
    </div>
      <button type="submit">Submit</button>
  </form>
</div>
```
- 表示は以下の通り
<img width="1128" alt="binding.png" src="https://qiita-image-store.s3.amazonaws.com/0/269592/6ea180a4-7526-3999-0220-0c53f7f9919e.png">

- これだけだとバインディングされているのか分からないので、employee.component.htmlの頭に以下を追記

```
<div>
    {{model|json}}
</div>
```
- すると以下のように入力値がjson形式で表示される

```
{ "id": 12, "name": "Angular", "phone": "060-1234-5678", "department": "Marketing"}
```

- 例えば部署をDesignerに変更すると、変更が即座に反映され、以下のように表示される

```

{ "id": 12, "name": "Angular", "phone": "060-1234-5678", "department": "Designer" }
```