技術

[Angular]リアクティブフォームのHTML側の記法

投稿日:

Angularのリアクティブフォームではtsファイル側でネストした構成を組むことができます。
HTMLファイルでもformGroupやformControlの名前を定義できるのですが、
tsファイルで定義した構成に合うようにしてあげる必要があります。

構成に誤りがあると、以下のようなエラーが出たりします。

ERROR Error: formControlName must be used with a parent formGroup directive.  You'll want to add a formGroup directive and pass it an existing FormGroup instance (you can create one in your class).

それでは例で見てみましょう。

htmlで構成を再現する

formGroupName、formControlName、formArrayNameの3種類をうまく使って構成を組み上げてあげましょう。
それぞれFormControl、 FormGroup、FormArrayにNameがついただけなのでわかりやすいですね。

例えば、tsファイルで以下のような構成で組んだ場合。

~~
formGroup: FormGroup;
roomMates: Array;

constructor( private fb: FormBuilder ){}

ngOnInit() {
  this.formGroup = this.fb.group({
    firstName: [''],
    lastName: [''],
    address: this.fb.group({
      street: [''],
      city: [''],
      state: [''],
      zip: ['111-1111']
    }),
    frends: this.fb.array([
      this.fb.control(''),
      this.fb.control('')
    ])
  });
}

テキストボックスではhtml側では以下のように書けばOKです。

<form [formGroup]="formGroup">
  <input type="text" formControlName="firstName">  // tsファイルでfirstNameとして設定したformControlと紐付け。
  <input type="text" formControlName="lastName"> 
  <div formGroupName="address">                    // tsファイルでaddressと設定したformGroupと紐付け。
    <input type="text" formControlName="street">   // ネストしたformControlはformGroupNameを設定した要素の中に配置
    <input type="text" formControlName="city"> 
    <input type="text" formControlName="state"> 
    <input type="text" formControlName="zip"> 
  </div>
  <div formArrayName="friends">
    <div *ngFor="let roomMate of roomMates; index as i" >
        <input type="text" formControlName="{{i}}"> 
    </div>
  </div>
</form>

なお、tsファイル側だけで設定するということもあると思いますが、
html側にformControlNameが足りなくてもエラーになりません。
formArrayNameやformGroupNameが足りなくとどうなるか知りませんが、多分エラーにならないと思います。

コンポーネントを分割した場合

子コンポーネントに切り分けてあげる場合、親と同等に構造を書いてあげる必要があります。
上記の例のaddressの中を分割したとします。

<form [formGroup]="formGroup">
  <input type="text" formControlName="firstName">  
  <input type="text" formControlName="lastName">
  <div formGroupName="address">
    <app-address-area [formGroup]="formGroup"></app-address-area> // address内をコンポーネント分割してformGroupを渡す。
  </div>
  <div formArrayName="friends">
    <div *ngFor="let roomMate of roomMates; index as i" >
      <input type="text" formControlName="{{i}}"> 
    </div>
  </div>
</form>

この場合、子コンポーネントでは以下のように書けばOKです。

<form [formGroup]="formGroup">
  <div formGroupName="address">
    <input type="text" formControlName="street">
    <input type="text" formControlName="city"> 
    <input type="text" formControlName="state"> 
    <input type="text" formControlName="zip"> 
  </div>
</form>

普通はformGroupName=”address”ごと分割する方が良いですが、
多少わかり安いかなと思い上記のように書いてみました。

-技術
-,

執筆者:


comment

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください

関連記事

no image

railsでA server is already running~とでたときの対処法

こんにちは!コーテッグの小山です。 rails使っていて、rails sをすると …

no image

TypescriptでMap使用時にコンパイルエラー

こんにちは 連想配列で重複を省く処理をしたい時にMapを使用することがあります。 …

no image

【Rails】Railsでsitemap.xmlを作成する

こんにちは Railsでsaitemap.xmlを作成する方法を紹介します。 s …

rails_logo

[Rails] image_tagを使わずにassets内の画像を指定する方法

こんにちは。さとうです。 今回はimage_tagを使わずにassets内の画像 …

no image

OSSに貢献してみたい人向けチュートリアルの紹介

こんばんは githubのtrendingを眺めてたら、OSSに貢献してみたい人 …