无法显示所有表单字段的Angular反应表单嵌套组

时间:2019-04-23 00:54:59

标签: nested angular-reactive-forms

当表单值看起来一切正常,但表单的某些部分没有显示。
看“对象3D”部分
我在这里错过了什么吗?

我尝试了任何方法,但没有成功:

*ngFor="let pos of myForm.get(position); let f = index "

*ngFor="let scl of myForm.get('obj3d')['controls'].scale; let g = index "

app-component.ts:

import { Component } from '@angular/core';
import { FormBuilder, FormGroup, FormArray, FormControl} from '@angular/forms';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  myForm: FormGroup;

  data = {
    building: "Building A",
    obj3d: [
      {
        asset: "my-assetfile.txt",
        position: {
          x: 1,
          y: 2,
          z: 3
        },
        scale: {
          x: 4,
          y: 5,
          z: 6
        }
      }
    ],
    overlay: [
      {
        asset: "my-secondasset.txt",
        h: 7,
        w: 8,
        x: 9,
        y: 10
      }
    ]
  }


  constructor(private fb: FormBuilder) {
    this.myForm = new FormGroup({
    building: new FormControl(''),
    obj3d: new FormArray([]),
    overlay: new FormArray([])
  });
    this.myForm.patchValue({building: this.data.building})
    this.setObj3d();
    this.setOverlay();
    console.warn(this.data);
  }

  setObj3d() {
    let control = <FormArray>this.myForm.controls['obj3d'];
    this.data.obj3d.forEach(p => {
      control.push(this.fb.group({ 
        asset: p.asset,
        position: this.fb.group({
          x: p.position.x,
          y: p.position.y,
          z: p.position.z
        }), 
        scale: this.fb.group({
          x: p.scale.x,
          y: p.scale.y,
          z: p.scale.z
        })
      }))
    })
  }

  setOverlay() {
    let control = <FormArray>this.myForm.controls['overlay'];
    this.data.overlay.forEach(q => {
      control.push(this.fb.group({
        asset: q.asset,
        h: q.h,
        w: q.w,
        x: q.x,
        y: q.y
      }))
    })
  }

  doSubmit() {
    const form = new FormData();
    console.log(JSON.stringify(this.myForm.value));
  }
}

app-component.html

<form [formGroup]="myForm" (ngSubmit)="doSubmit()">
	<fieldset>
		<legend>
			<h3>Floor: </h3>
		</legend>
		<label>Building: </label><input formControlName="building" />
    <div formArrayName="obj3d">
      <div *ngFor="let obj of myForm.get('obj3d').controls; let k=index">

        <fieldset>
        <legend><h4>Object 3D</h4></legend>
        <div [formGroupName]="k">
          <label>Asset:</label><input formControlName="asset" />
          <div [formGroupName]="position" *ngFor="let pos of myForm.get(position); let f = index ">
            <fieldset>
            <legend><h4>Position</h4></legend>
                <label>X:</label><input formControlName="x"/>
                <label>Y:</label><input formControlName="y"/>
                <label>Z:</label><input formControlName="z"/>
            </fieldset>
          </div>
          <div [formGroupName]="scale" *ngFor="let scl of myForm.get('obj3d')['controls'].scale; let g = index ">
            <fieldset>
            <legend><h4>Scale</h4></legend>
                <label>X:</label><input formControlName="x"/>
                <label>Y:</label><input formControlName="y"/>
                <label>Z:</label><input formControlName="z"/>
            </fieldset>
          </div>
        </div>
        </fieldset>
      </div>
    </div>

    <div formArrayName="overlay">
      <div *ngFor="let obj of myForm.get('overlay').controls; let j=index">
        <fieldset>
        <legend><h4>Overlay</h4></legend>
        <div [formGroupName]="j">
          <label>Asset:</label><input formControlName="asset" />
          <label>H:</label><input formControlName="h" />
          <label>W:</label><input formControlName="w" />
          <label>X:</label><input formControlName="x" />
          <label>Y:</label><input formControlName="y" />
        </div>
        </fieldset>
      </div>
    </div>

  </fieldset>
  <br>
  <button type="submit" class="btn" >Submit</button>  
</form>

<pre>{{myForm.value | json}}</pre>

我希望所有表单字段都在显示,仅当我删除此迭代项时才会显示

 *ngFor="let pos of myForm.get(position); let f = index "

但是会产生一些错误:

ERROR
Error: Cannot find control with path: 'obj3d -> 0 -> '

提交后登录即可:

{
    "building": "Building A",
    "obj3d": [{
        "asset": "my-assetfile.txt",
        "position": {
            "x": 1,
            "y": 2,
            "z": 3
        },
        "scale": {
            "x": 4,
            "y": 5,
            "z": 6
        }
    }],
    "overlay": [{
        "asset": "my-secondasset.txt",
        "h": 7,
        "w": 8,
        "x": 9,
        "y": 10
    }]
}

Demo Code

任何帮助将不胜感激

1 个答案:

答案 0 :(得分:0)

问题已解决,只需取消绑定

   <div formArrayName="obj3d">
  <div *ngFor="let obj of myForm.get('obj3d').controls; let k=index">
    <fieldset>
    <legend><h4>Object 3D</h4></legend>
    <div [formGroupName]="k">
      <label>Asset:</label><input formControlName="asset" />
        <div formGroupName="position">
        <fieldset>
        <legend><h4>Position</h4></legend>
            <label>X:</label><input formControlName="x"/>
            <label>Y:</label><input formControlName="y"/>
            <label>Z:</label><input formControlName="z"/>
        </fieldset>
      </div>
      <div formGroupName="scale">
        <fieldset>
        <legend><h4>Scale</h4></legend>
            <label>X:</label><input formControlName="x"/>
            <label>Y:</label><input formControlName="y"/>
            <label>Z:</label><input formControlName="z"/>
        </fieldset>
      </div>
    </div>
    </fieldset>

  </div>
</div>