web-dev-qa-db-ja.com

Angular 2ネストされたコンポーネントを持つ反応フォームの作成

私の要件は、ネストされたコンポーネントを持つフォームを作成する必要があることです。各フォームフィールドのコンポーネントを作成しています。テキストボックスには1つのコンポーネントがあり、ラジオボタンには別のコンポーネントがあります。
<form [formGroup]="myForm">
<textbox-component></textbox-component>
<radioButton-component></radioButton-component>
</form>

また、HTMLをそのままにして、TypeScriptのみでフォームを検証できるようにするため、このフォームの作成にはReactiveフォームを使用したいと思います。

しかし、私はどのようにしてコンポーネントと入れ子になった反応フォームを持つことができるのか、どんな解決策も見つけることができません。

34

研究と実験の結果、質問に対する答えが1つ見つかったので、自分で答えてください。それが誰かの時間を節約するなら、私は幸せになります。

ネストされたコンポーネントを持つ反応フォームを作成したい場合は、以下のようにすることができます

ここでは、テキストボックス用とラジオボタン用の2つのネストされたコンポーネントを持つフォームを作成しています

あなたの親コンポーネントはこのようにすることができます

<form [formGroup]="myForm">
    <child-textbox-component [parentFormGroup]="myForm">
    </child-textbox-component>
    <child-radio-button-component [parentFormGroup]="myForm">
    </child-radio-button-component>
</form>

親コンポーネントで作成された子コンポーネントへの入力としてFormGroupオブジェクトを子コンポーネントへの入力として渡します。それらはコンポーネントでこのFormGroupオブジェクトを使用して、クラスの特定のコントロールを設計します。

子コンポーネントは次のようになります

child-textbox-component

<div class="form-group" [formGroup]="parentFormGroup">
  <label>
    {{control.caption}}
  </label>
  <input class="form-control" type="text" [title]="control.toolTip" 
    [attr.maxlength]="control.width" [name]="control.name"
    [value]="control.defaultValue" [formControlName]="control.name"/>
</div>

子ラジオボタンコンポーネント

<div class="form-group" [formGroup]="parentFormGroup">
  <label>
    {{control.caption}}
  </label>
  <div>
      <label *ngFor="let value of control.values; let idx = index"
        class="radio-inline" [title]="control.tooltip">
        <input type="radio" [name]="control.name" [formControlName]="control.name"/>
        {{ value }}
      </label>
  </div>
</div>

ここでのコントロールは、これらの子コンポーネントに対して表示されるデータを保持するモデルクラスです。

この方法では、ネストされたコンポーネントを使用してフォームを生成できるため、単一のコンポーネントにフォーム(大きなフォームと言える)を含める必要はありません。 angular 2のリアクティブフォームを使用して、サブコンポーネントとフォームを簡単に作成および維持できるように、それを分解することができます。2。検証も簡単に追加できます。

これに答える前に私はこれらのリンクをたどりました

  1. stackoverflowで類似したもの

  2. 角度2動的形式

54

Mheshの回答に対する追加の注記として、HTMLに[parentFormGroup]を挿入せずにこの同じソリューションを構築できます。これを行うには、再利用可能なフォームグループで Stack Overflow post を実行します。

これは本当にいいです。

既存のソリューションを使用するには、次の点を除いて同じことを行うことができます。

親コンポーネントは、追加のパラメーターを渡さずに、このようにすることができます

<form [formGroup]="myForm">
    <child-textbox-component></child-textbox-component>
    <child-radio-button-component></child-radio-button-component>
</form>

さらに、次のようにフォームグループを設定できることに注意してください:

<form [formGroup]="myForm">
    <child-textbox-component></child-textbox-component>
    <child-radio-button-component formGroupName="myGroup"></child-radio-button-component>
</form>

child-textbox-component

<div class="form-group" [formGroup]="controlContainer.control">
  <label>
    {{control.caption}}
  </label>
  <input class="form-control" type="text" [title]="control.toolTip" 
    [attr.maxlength]="control.width" [name]="control.name"
    [value]="control.defaultValue" [formControlName]="control.name"/>
</div>

これを有効にするには、@ComponentControlContainerを挿入します

@Component({
    moduleId: `MODULE_ID_HERE`,
    selector: "child-textbox-component",
    templateUrl: "childTextbox.component.html",
})
export class ChildTextboxComponent {
    constructor(private controlContainer: ControlContainer, OTHER_PARAMETERS) {
    }
}
3
Stormswept

可能な回答のリストを拡張するために、 このAlexey Zuevによる記事 は、コンポーネントデコレータでprovide:ControlContainerおよびuseExisting:NgFormngFormディレクティブを子コンポーネントに渡す方法。

@Component({
  selector: 'registrant',
  templateUrl: 'app/register/registrant.component.html',
  **viewProviders: [ { provide: ControlContainer, useExisting: NgForm } ]**
})
1
PoorInRichfield

[formGroup]バインディングを使用して、同じまたはサブのformGroupをフォームブロックに渡すだけです。

0
xsilen T