(角度)聆听反应式子表单组的验证更改

时间:2020-05-02 17:09:17

标签: angular angular-reactive-forms angular-forms angular-validation

在我的主要组件中,我渲染一个表单,其表单组位于子组件中。主要组件使用一些默认值进行初始化,子组件使用一些验证器和其他逻辑进行初始化。

现在,我正在考虑在主表单上进行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 个答案:

答案 0 :(得分:1)

在侦听更改的主组件中,formBuilder没有任何验证。仅在子组件中对它们进行验证。如果您侦听子组件中的更改,则可能会看到表单并非始终有效。 您可以使用EventEmitter侦听子组件并将其发送到主组件,也可以向主组件中的表单实例添加验证。

为确保您可以调试并检查main.component中的表单中是否有任何验证

答案 1 :(得分:0)

子级有自己的表单,没有链接到父级表单,您需要将表单组传递给子级组件:

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