Angular2 フォームで ReactiveFormsModule と FormBuilder サービスを一緒に使う
Angular2 フォームで formGroup にバインドできない問題の解決策
原因
- ReactiveFormsModule のインポート漏れ:
formGroup
は ReactiveFormsModule
に属するディレクティブであるため、このモジュールをインポートしていないとエラーが発生します。
- formGroup ディレクティブの参照漏れ:
formGroup
ディレクティブをテンプレートで使用するには、コンポーネントクラスで FormGroup
インスタンスを作成し、テンプレート内で formGroup
ディレクティブとバインドする必要があります。
- formControlName ディレクティブの漏れ:
formGroup
と一緒に formControlName
ディレクティブも使用して、個々のフォームコントロールをテンプレートの HTML 要素にバインドする必要があります。
- モジュールの誤設定:
FormsModule
と ReactiveFormsModule
は同時にインポートできません。フォームの種類に応じて、どちらか一方のみをインポートする必要があります。
解決策
app.module.ts
ファイルに ReactiveFormsModule
をインポートします。
import { ReactiveFormsModule } from '@angular/forms';
@NgModule({
imports: [
BrowserModule,
ReactiveFormsModule,
],
...
})
export class AppModule {}
import { FormGroup, FormControl } from '@angular/forms';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
})
export class AppComponent {
formGroup: FormGroup = new FormGroup({
name: new FormControl(''),
});
}
<form [formGroup]="formGroup">
<input type="text" formControlName="name">
</form>
<form [formGroup]="formGroup">
<input type="text" formControlName="name">
</form>
- モジュール設定を確認する:
その他のヒント
- エラーメッセージをよく読んで、問題の原因を特定してください。
app.component.ts:
import { Component, OnInit } from '@angular/core';
import { FormGroup, FormControl } from '@angular/forms';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
})
export class AppComponent implements OnInit {
formGroup: FormGroup;
constructor() {}
ngOnInit() {
this.formGroup = new FormGroup({
name: new FormControl(''),
email: new FormControl(''),
});
}
}
<form [formGroup]="formGroup">
<label for="name">名前:</label>
<input type="text" id="name" formControlName="name">
<label for="email">メールアドレス:</label>
<input type="email" id="email" formControlName="email">
<button type="submit">送信</button>
</form>
このコードを実行すると、フォームが表示され、ユーザーは名前とメールアドレスを入力することができます。
その他のサンプル
以下のサンプルコードも参考にしてください。
Angular2 フォームで formGroup にバインドする他の方法
テンプレート構文を使用する
<form [formGroup]="formGroup">
<input type="text" formControlName="name">
</form>
formGroup ディレクティブを使用する
<form #myForm="ngForm">
<input type="text" [(ngModel)]="name">
</form>
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
})
export class AppComponent {
name: string;
constructor() {
this.name = '';
}
onSubmit() {
// フォーム送信時の処理
}
}
FormBuilder サービスを使用する
import { FormBuilder, FormGroup, FormControl } from '@angular/forms';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
})
export class AppComponent {
formGroup: FormGroup;
constructor(private fb: FormBuilder) {}
ngOnInit() {
this.formGroup = this.fb.group({
name: new FormControl(''),
email: new FormControl(''),
});
}
}
ReactiveFormsModule モジュールを使用する
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { ReactiveFormsModule } from '@angular/forms';
@NgModule({
imports: [
BrowserModule,
ReactiveFormsModule,
],
...
})
export class AppModule {}
formGroup ディレクティブと formControlName ディレクティブを一緒に使用する
<form [formGroup]="formGroup">
<input type="text" formControlName="name">
</form>
formGroup ディレクティブと ngModel ディレクティブを一緒に使用する
<form #myForm="ngForm">
<input type="text" [(ngModel)]="name">
</form>
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
})
export class AppComponent {
name: string;
constructor() {
this.name = '';
}
onSubmit() {
// フォーム送信時の処理
}
}
FormBuilder サービスと ReactiveFormsModule モジュールを一緒に使用する
import { FormBuilder, FormGroup, FormControl } from '@angular/forms';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
})
export class AppComponent {
formGroup: FormGroup;
constructor(private fb: FormBuilder) {}
ngOnInit() {
this.formGroup = this.fb.group({
name: new FormControl(''),
email: new FormControl(''),
});
}
}
上記の方法のどれを選択しても、Angular2 フォームで formGroup
にバインドすることができます。
上記の例を参考に、自分に合った方法を選択して、Angular2 フォームで formGroup
にバインドしてください。
angular typescript angular2-forms