(Angular) Прослушайте изменения проверки из групп реагирующих дочерних форм - PullRequest
1 голос
/ 02 мая 2020

В моем основном компоненте я отображаю форму, группы форм которой находятся в дочерних компонентах. Основной компонент инициализируется с некоторыми значениями по умолчанию, а дочерние компоненты инициализируются самими некоторыми валидаторами и другими логами c.

Теперь я думал, что при подписке valueChanges в главной форме главный компонент получает изменения в дочерней форме группируется как-то автоматически. Но отсутствует связующий элемент, поскольку форма всегда «действительна», даже если в дочерних группах форм есть ошибки проверки.

Что я пропустил?

main.component.ts:

ngOnInit() {
    this.initializeFormGroup();
    this.form.valueChanges.subscribe(
      result => console.log(this.form.valid); // always outputs true!?
    );
  });
}

private initializeFormGroup(): void {
  this.form = this.formBuilder.group({
    child1: this.formBuilder.group({}),
    child2: this.formBuilder.group({})
  });
}

main.component. html:

<form [formGroup]="form">
  <child1></child1>
  <child2></child2>
</form>

child1.component.ts:

form: FormGroup;

ngOnInit(): void {
  this.initializeFormGroup();
  this.checkStuffAndAddValidators();
}


get formArray(): FormArray {
  return this.form.get('array') as FormArray;
}

private initializeFormGroup(): void {
  this.form = this.formBuilder.group({
    array: this.formBuilder.array([])
  });
}

private checkStuffAndAddValidators(): any {
    const newGroup = this.formBuilder.group({
      inputA: ['', [Validators.required]],
      inputB: ['']
    });

    if (this.someConditionIsTrue) {
      newGroup
        .get('inputB')
        .setValidators([MyValidator]);
      newGroup.updateValueAndValidity();
    }

    this.array.push(newGroup);
  });
}

child1.component. html:

<div [formGroup]="form">
  <div formArrayName="array" *ngFor="let control of formArray.controls; let i = index">
  <ng-container formGroupName="{{ i }}">
    <input name="inputA" formControlName="inputA" />
    <input name="inputB" formControlName="inputB" />
  </ng-container>
</div>

child2.component.ts:

form: FormGroup;

ngOnInit(): void {
  this.initializeFormGroup();
}

get formArray(): FormArray {
  return this.form.get('array') as FormArray;
}

addInput() {
  if (!this.formArray.valid) {
    return;
  }
  this.formArray.push(this.createNewFormGroup());
}

removeInput(index: number) {
  this.formArray.removeAt(index);
}

private initializeFormGroup(): void {
  this.form = this.formBuilder.group({
    array: this.formBuilder.array([this.createNewFormGroup()])
  });
}

private createNewFromGroup(): FormGroup {
return this.formBuilder.group({
  inputA: ['', [Validators.required]],
  inputB: ['', [Validators.required]]
});

child2.component. html:

<div [formGroup]="form">
  <div formArrayName="array" *ngFor="let control of formArray.controls; let i = index">
  <ng-container formGroupName="{{ i }}">
    <input name="inputA" formControlName="inputA" />
    <a (click)="removeInput(i)">del</a>
    <a (click)="addInput()">add</a>
    <input name="inputB" formControlName="inputB" />
    <a (click)="removeInput(i)">del</a>
    <a (click)="addInput()">add</a>
  </ng-container>
</div>

Ответы [ 2 ]

1 голос
/ 02 мая 2020

В основном компоненте, где вы слушаете изменения, formBuilder не имеет никаких проверок. Только в дочерних компонентах они проверяются. Если вы прослушиваете изменения в дочерних компонентах, вы можете увидеть, что форма не всегда действительна. Вы можете прослушивать дочерние компоненты и отправлять их в основной компонент, используя EventEmitter, или вы можете добавить проверки к экземпляру формы в основном компоненте.

Чтобы убедиться, что вы можете отладить и проверить, есть ли какие-либо проверки в вашей форме в main.component

0 голосов
/ 02 мая 2020

Дочерние объекты имеют свои собственные формы и не связаны с родительской формой, если вам необходимо передать группы форм дочерним компонентам:

<form [formGroup]="form">
  <child1 [form]="form.get('child1')></child1>
  <child2 [form]="form.get('child2')></child2>
</form>
...