【问题标题】:(Angular) Listen to validation changes from reactive child form groups(Angular) 监听来自响应式子表单组的验证更改
【发布时间】:2020-08-17 04:06:27
【问题描述】:

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

现在我在想,通过主窗体上的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>

【问题讨论】:

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


    【解决方案1】:

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

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

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

        猜你喜欢
        • 2018-12-11
        • 2017-08-28
        • 1970-01-01
        • 2022-01-23
        • 2018-06-07
        • 1970-01-01
        • 2020-10-16
        • 2020-02-17
        • 2020-01-13
        相关资源
        最近更新 更多