Angular　フォーム作成　2パターンから

■ 登場ファイル
・login/login.component.ts
・login/login.component.html
・app.module.ts

<h1>Form作成は2パターンある</h1>

<b>①1回ずつform作成毎にFormControlを作成し､FormGroupに追加していく方法</b>
<b>②formbuilderを定義して、form作成追加回しする方法</b>


<h1>①の作成手順</h1>

②の手順でもhtmlは使い回します。(formGroup)をloginFormにする。

```login.component.html

<form class="login-form" [formGroup]="loginForm" (ngSubmit)="onSubmit()">
  <input type="userId"  name="user_id" formControlName="userId" class="login-userId" autofocus="true" required="true" placeholder="UserId" />
  <input type="email"  name="email_id" formControlName="email" class="login-email" autofocus="true" required="true" placeholder="Email" />
  <input type="password" name="password" formControlName="password" class="login-password" required="true" placeholder="Password" />
  <input type="submit" name="button" value="Login" class="login-submit" id="login_submit" />
</form>

```

```app.module.ts

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

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { HeaderComponent } from './header/header.component';
import { LoginComponent } from './login/login.component';
//Form関連↓
import { FormsModule, ReactiveFormsModule } from '@angular/forms';

@NgModule({
  declarations: [
    AppComponent,
    HeaderComponent,
    LoginComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    //Form関連↓
    FormsModule,
    ReactiveFormsModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }


```

ここから、login.component.ts①②で記述方法が異なります。

```login.component.ts
import { Component, OnInit, OnDestroy, NgModule } from '@angular/core';
import { FormGroup, FormControl} from '@angular/forms'; //B
import { Router } from '@angular/router';

@Component({
  selector: 'app-login',
  templateUrl: './login.component.html',
  styleUrls: ['./login.component.scss']
})

export class LoginComponent implements OnInit, OnDestroy {

  constructor(
    private router: Router,//画面遷移用
  ) {
  }

  // フォーム内で使用する項目の生成　A
  loginForm = new FormGroup({
    userId: new FormControl('', []),
    email: new FormControl('', []),
    password: new FormControl('', []),
  });
  
  onSubmit() { //C
    alert(JSON.stringify(this.loginForm.value));
    console.log(JSON.stringify(this.loginForm.value));
    this.router.navigate(['home']);
  }

  ngOnDestroy(): void {
    
  }

  ngOnInit(): void {
  }
}

```

A = フォーム内で使用する項目生成
B = 必要import
C = 情報を取得(loginForm)出来ているか確認

こんな感じで、alertが出ればformGroupは正常に機能していると判断して良いと思います。

![スクリーンショット 2022-08-06 11.17.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/677104/707cf9b9-9da0-3a09-8d1a-ddd2557ac464.png)


<h1>②の作成手順</h1>

```login.component.ts
import { Component, OnInit, OnDestroy, NgModule } from '@angular/core';
import { FormGroup, FormControl, FormBuilder, Validators} from '@angular/forms'; //A
import { Router } from '@angular/router';

@Component({
  selector: 'app-login',
  templateUrl: './login.component.html',
  styleUrls: ['./login.component.scss']
})

export class LoginComponent implements OnInit, OnDestroy {

  constructor(
    private router: Router,//画面遷移用
    private fb: FormBuilder //B
  ) {
  }

  //C
  loginForm = this.fb.group({
    userId: ['', Validators.required],//[初期値、必須項目設定]
    email: ['',Validators.required],
    password: ['',Validators.required]
  })
  
  //D
  onSubmit() {
    alert(JSON.stringify(this.loginForm.value));
    console.log(JSON.stringify(this.loginForm.value));
    this.router.navigate(['home']);
  }

  ngOnDestroy(): void {
    
  }

  ngOnInit(): void {
  }
}

```

コメントアウトのABCDが該当箇所です。

A = ①と違い、 FormBuilder, Validatorsをimportしています。
B = constructorに、 FormBuilderを追加しました。( 補：fb名は任意です。 )
C = htmlに記述してる、htmlのloginFormで定義する。
D = formで入力した値をsubmit　Tap時にalertで表示する処理

```login.component.html
<form class="login-form" [formGroup]="loginForm" (ngSubmit)="onSubmit()">
```

```
説明：第一引数を空にして、 必須項目とするにはvalidators.requriredを第二引数に。
    userId: ['', Validators.required],//[初期値、必須項目設定]

```