はまったりひらめいたり…とか…

Angularや.NETやAzureやその他色々。

Reactive FormsでオリジナルのComponentを使用する

初めに

今回の記事は、下記構成でお送りします。

  • Angular: 5.1.1
  • AngularCli: 1.6.1

Reactive FormsでOriginalのComponentを使いたい

業務系のWebApp作るお仕事してるとReactive Formsを多用します。

Validatorのエラーチェック部分を楽に作れるのが気に入ってます。

ただ、DBから引っ張ってきたマスタListのSelectBoxとか

多くのところで使用するようなコントロールは共通化したいところです。

そこで、Component部品をReactive Formsで使用できないか試してみました。

まずは単純なReactive Forms

ログイン画面っぽいもの想定して、単純なReactive Formsの画面を作ってみます。

<form [formGroup]="inputForm">
  <input [formControlName]="USER_ID_KEYWORD" placeholder="ユーザーID" />
  <label style="color:red" *ngIf="formErrors[USER_ID_KEYWORD]">{{formErrors[USER_ID_KEYWORD]}}</label>
  <br/>
  <input [formControlName]="PASSWORD_KEYWORD" placeholder="パスワード" />
  <label style="color:red" *ngIf="formErrors[PASSWORD_KEYWORD]">{{formErrors[PASSWORD_KEYWORD]}}</label>
</form>

ユーザーIDコントロールだけ切り出し、別Componentに

  • ユーザーIDコントロールapp-user-id-textという名前で作成しました
<form [formGroup]="inputForm">
  <app-user-id-text [formControlName]="USER_ID_KEYWORD"></app-user-id-text>
  <label style="color:red" *ngIf="formErrors[USER_ID_KEYWORD]">{{formErrors[USER_ID_KEYWORD]}}</label>
  <br/>
  <input [formControlName]="PASSWORD_KEYWORD" placeholder="パスワード" />
  <label style="color:red" *ngIf="formErrors[PASSWORD_KEYWORD]">{{formErrors[PASSWORD_KEYWORD]}}</label>
</form>

まずは、単純に、新しく作成したComponentに

ユーザーIDで使用してたFormControlNameを使用してみます。

エラー

f:id:TakasDev:20171221220818j:plain

ですよねー。ってことで修正します。

Reactive Formsの作り方を思い出す

Reactive Formsは、ComponentのInit時に、下記のように作成したはずです。

buildForm() {
    this.inputForm = this.fb.group(this.formSetting);
    this.inputForm.valueChanges.subscribe(data => {
        this.onValueChange(data);
    });
    this.onValueChange();
}

FormのSetting情報を、FormBuilder.groupを使用して

FormGroupプロパティに突っ込んでいます。

つまり、Componentに対してFormGroupの情報を送ってやれば良いのかもしれません。

子ComponentにFormGroupのプロパティを生やす

@Input() fg: FormGroupのプロパティを生やしました。

export class UserIdTextComponent implements OnInit {

  @Input()
  fg: FormGroup;

...
}

Componentを使用する際に

<app-user-id-text [fg]="hogeForm"> ... みたいな感じで使用します。

結果

f:id:TakasDev:20171221221321g:plain

通りました。

入力内容が@InputのFormGroupを通して、親Componentに伝播し

また、オリジナルComponentのValidationエラーが

親Componentのエラーメッセージプロパティに格納されました。

最後に

今回作成したコードは、下記にあげてあります。

煮るなり焼くなりお好きにしてくださいませ。

github.com

…Angular v2時代に作った勉強用のリポジトリそろそろ名前変えないとなぁ…