技術

[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】idのauto increment設定を削除する

こんにちは railsを触っていてidからauto incrementの設定を削 …

[Bitbucket] fatal: Could not read from remote repository.

どうも中田です こないだリモートリポジトリにPushできないんすけど〜という話を …

no image

rubyでシンボリックリンクを作成する

rubyでシンボリックリンクを作る機会がありました。 どちらも、srcへのシンボ …

[Xcode] SDK Version Issue – This app was built with the iOS 12.0 SDK. Starting March 2019, all iOS apps submitted to the App Store must be built with the iOS 12.1 SDK or later, included in Xcode 10.1 or later.

こんにちは。たなかです。 2019年、ブログ初更新になります。今年もよろしくお願 …

no image

【Angular】Full calendarで横スクロールを実装

こんにちは Full Calendarにはいくつかの表示モードがあります。 こち …