Создайте FormArray в отдельном компоненте. не обновляет форму

Здравствуйте, я искал день об этом. Кажется, я не могу найти хороший ответ, поэтому я решил опубликовать что-нибудь здесь. Что я пытаюсь сделать, так это то, что в отдельном компоненте я хотел бы, чтобы 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>

к хтмл.

Затем я смог заставить форму привязываться к компоненту, а затем кнопка сохранения стала неактивной, когда это предполагалось. ЗДОРОВО!

Итак, я начал с массива форм и сделал еще несколько изменений:

в дочернем шаблоне я изменил на:

<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. Пожалуйста, передайте один.

также я считаю, что из-за этой ошибки он больше не обновляет родительскую форму. Как я могу получить массив для обновления родительской формы?

любая помощь будет высоко оценена.


person 3xGuy    schedule 14.02.2018    source источник


Ответы (1)


Поздний ответ, но на случай, если вы придете к этому. Вам всегда понадобится форма, окружающая ваш дочерний компонент:

<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), он также будет обновлен там.

person PeterS    schedule 29.10.2020