web-dev-qa-db-ja.com

Angular FormArray:テンプレートに動的に追加されたFormControlを参照しています

Angularリアクティブフォームに取り組んでいます。FormControlをいくつかFormArrayに動的に追加しましたが、formControlNameでバインドするときに、テンプレート内のこれらのFormControlを参照する際に問題が発生します。割り当てたテンプレートでインデックス変数「i」をformControlNameにループしますが、機能しません。コントロールをformControlNameにバインドすると、「パス付きのフォームコントロールの値アクセサーがありません」というメッセージが表示されます。コンポーネントクラスコードは次のとおりです。

export class Control {
  constructor(public controlType?: string, public label?: string, public required?: boolean, public placeholder?: string,
    public options?: string[], public value?: string) { }
}

export class FormComponent implements OnInit {
  reviewForm: FormGroup;

  constructor(public formService: FormService, public dialog: MdDialog) { }


  selectedControl: any = null;
  label: string;

  ngOnInit() {
    this.reviewForm = new FormGroup({
      'controlArray': new FormArray([
      ])
    });
  }

  addControl() {
    const myControl: Control = new Control(this.selectedControl.name, this.label, this.isRequired,
      this.selectedControl.attributes.value, this.selectedControl.attributes.options, 'null');
    var control: FormControl = new FormControl(myControl);
    (<FormArray>this.reviewForm.get('controlArray')).Push(control);
  }

}

そしてそれは私のコンポーネントのテンプレートです:

<form [formGroup]="reviewForm" (ngSubmit)="onSubmit()">
  <div class="example-label">
    <span class='block'>    
              <span *ngIf="selectedForm">
                      <h2 class="example-heading">{{displayForm}} </h2>
              </span>
    <div formArrayName="controlArray">
      <div *ngFor="let control of reviewForm.get('controlArray').controls; let i = index">
        <table>
          <tr>
            <span *ngIf="control.value">
                    <td> 
                      <label>{{control.value.label}}</label>                           
            </td>
            <td><span *ngIf="control.value.controlType == 'select'">                
                      <md-select placeholder="{{control.value.label}}" [formControlName]="i" >
                        <md-option *ngFor="let option of control.value.options; let i=index" 
                        [value]="option">{{control.value.options[i]}}</md-option>                  
                      </md-select>
                    </span></td>
            <td> <span *ngIf="control.value.controlType == 'text'">
              <md-form-field class="example-full-width">
                <input mdInput type="text" placeholder="{{control.value.placeholder}}" [formControlName]="i" >
              </md-form-field>  
          </span></td>
            <td> <span *ngIf="control.value.controlType == 'radio'">
              <md-radio-group>
                      <span *ngFor="let option of control.value.options">
                        <md-radio-button name="gender" value="{{option}}" [formControlName]="i" >{{option}} </md-radio-button>
                      </span>
              </md-radio-group>
              </span>
            </td>
            <td> <span *ngIf="control.value.controlType == 'checkbox'">
                      <md-checkbox value="{{control.value.controlType}}" [formControlName]="i" > </md-checkbox>
                    </span></td>

            <td> <span *ngIf="control.value.controlType == 'textarea'">
                      <textarea name="Comment" id="" cols="30" rows="10" [formControlName]="i" ></textarea>  
                    </span></td>

            <td> <span *ngIf="control.value.controlType == 'button'">
                        <button md-raised-button value="{{control.value}}" [formControlName]="i" >Button</button>  
                    </span> </td>
            </span>
          </tr>
        </table>
      </div>
    </div>
    </span>
  </div>
</form>

私のコンポーネントクラスでは、FormGroupにFormArrayしかありません。 addControl関数で、カスタムコントロールを作成し、このコントロールを最初のパラメーターとしてFormControlに渡しました。その後、このFormControlをFormArrayにプッシュします。テンプレートでformControlNameをFormControlsに関連付ける方法を教えてください。ありがとう

5
Waleed Shahzaib

この方法でバインドできます。

reviewForm.controls.controlArray.controls[i].controls.DATAYOULIKEBIND.value
3
lesimoes

私は同じ問題を抱えていて、コンポーネントクラスのゲッターでそれを解決しました。

get controlArray(): FormArray {
    return <FormArray> this.reviewForm.get('controlArray');
}

FormArrayへのキャストに注意してください。そうしないと、ゲッターがAbstractControlを返し、配列のプロパティや関数にアクセスできなくなります。

次に、テンプレートで次のようなことを行うことができます。

<div formArrayName="controlArray">
    <div *ngFor="let control of controlArray.controls; let i = index" >
1
Ben Thurley

あなたはこのようなことをすべきです。 formArrayを追加した次のdivに[formGroupName] = iを追加します。 Angularは正しいトラバーサルを知っています。これが役立つことを願っています。以前に同じ問題が発生しましたが、この修正が役に立ちました。

<div formArrayName="controlArray"> <div [formGroupName]=i *ngFor="let control of reviewForm.get('controlArray').controls; let i = index">

0
Karthik