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

.Net系プログラムで勉強したこととか嵌ったことについて書いたりします。

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時代に作った勉強用のリポジトリそろそろ名前変えないとなぁ…