在单独的组件中创建FormArray。不更新表单

时间:2018-02-14 14:03:44

标签: angular-reactive-forms angular4-forms

您好我已经搜索了一天这个。我似乎无法找到一个好的anwser,所以我想我会在这里发布一些东西。我想要完成的是,在一个单独的组件中,我希望FormArray能够从父组件传递此内容,并且当该表单变为无效时,它将禁用父保存按钮。

所以我开始寻找这个,并找到了这样做的地方(我做了一些修改,它在Plunker上完成了。我添加了这段代码:

let person = new Person();
person.name='James';
person.address=new Address();
person.address.street='123 main street';
person.address.zip = '22222';

this.myForm.reset({
  name:person.name
});
this.myForm.controls.address.reset({
  street:this.person.address.street,
  zip:this.person.address.zip
});

到on init方法,并且:

<app-child [address]="myForm.controls.address"></app-child>      
<button class="btn btn-primary" [disabled]="!myForm.valid" >save</button>

到html。

然后我能够将表单绑定到组件,然后保存按钮在应该的时候被禁用。 GREAT!

然后我开始使用表单数组,并进行了一些修改:

儿童模板中的

我改为:

<div>
   <button class="btn btn-success" (click)="add()">+</button>
   <button class="btn btn-danger">-</button>
</div>
<div formArrayName="addresses" *ngFor="let address of addresses.controls; let i=index">
  <div [formGroup]="i">
    <label>Street: </label>
    <input formControlName="street"><br>
    <label>Zip: </label>
    <input formControlName="zip">
  </div>
</div>

将AppChild更改为:

export class AppChild {

  constructor(
    private formBuilder:FormBuilder
  ){}

  @Input() addresses: FormArray;

  add():void{
    let address = this.formBuilder.group({
      street:['', Validators.required],
      zip:['']
    });
    this.addresses.push(address);
  }
}

,myAppComponent现在看起来像:

@Component({
  selector: 'app-root',
  styleUrls: ['./app.component.css'],
  template:`

  <h3>Nested FormGroup</h3>

  <form [formGroup]="myForm">
    <label>Name: </label>
    <input formControlName="name" />
    <app-child [addresses]="myForm.controls.addresses"></app-child>

    <button class="btn btn-primary" (click)="onClick()">save</button>
  </form>
  <br>
  <pre>Form Values: {{myForm.value | json}}</pre>
`,
})
export class App {

myForm: FormGroup

constructor(private fb: FormBuilder) {}

ngOnInit() {
  this.myForm = this.fb.group({
    name: ['', Validators.required],
    addresses: this.fb.array([ this.getAddress()])
  });

  let person = new Person();
  person.name='James';

  this.myForm.reset({
    name:person.name
  });
}

onClick():void{
  let a ='b';
  alert(this.myForm.valid);
}

getAddress():FormGroup{
  return this.fb.group({
    street: ['', Validators.required],
    zip: ['']
  });
}

}

所以现在我收到了这个错误:

  

错误:formGroup需要一个FormGroup实例。请通过一个。

我也认为由于此错误,它不再更新父表单。如何让数组更新父表单?

任何和所有帮助将不胜感激。

1 个答案:

答案 0 :(得分:0)

最新答案,但以防万一。您将始终需要一个围绕子组件的表格:

<section [formGroup]="container">
    <div>
       <button class="btn btn-success" (click)="add()">+</button>
       <button class="btn btn-danger">-</button>
    </div>
    <div formArrayName="addresses" *ngFor="let address of addresses.controls; let i=index">
      <div [formGroup]="i">
        <label>Street: </label>
        <input formControlName="street"><br>
        <label>Zip: </label>
        <input formControlName="zip">
      </div>
    </div>
</section>

然后在您的子组件中:

export class AppChild {

  @Input() addresses: FormArray;

  container: FormGroup;

  constructor(
    private formBuilder:FormBuilder
  ){
    this.container = new FormGroup({});
  }



  ngOnInit(): void {
    this.container.addControl('addresses', addresses);
  }

  add():void{
    let address = this.formBuilder.group({
      street:['', Validators.required],
      zip:['']
    });
    this.addresses.push(address);
  }
}

由于表单数组已经与更高级别的formGroup(myForm)关联,因此也会在其中进行更新。