在提交时验证子组件

validating a child component on submit

我一直在网上寻找,找不到任何答案。

我正在使用 angular 10 和反应形式。

这是我的问题:单击提交按钮会在按钮级别而非子组件级别触发表单的有效性

这是StackBlitz

如果您在此示例中按“保存”,您将仅看到第一个输入触发验证并变为红色,而另一个需要手动单击。我有一个带有 2 个控件的 formGroup,一个是 FormControl,另一个是 FormArray。我将主 formGroup 传递给子组件并在 formArray 中推送 1 formGroup,这个 formGroup 有一个 formControl。所以基本上我在叶子上有两个 FormControl。如果这没有意义,请告诉我。

因此,我希望检查所有元素的有效性,无论它是否在子组件内。

对于诉讼案例,假设您有带有子小部件场景的仪表板

  1. NGX-Sub-Form works well as a turnkey, I like this approach because it breaks up the complexity as a second/level sub form只需扩展其中的4个classes/options

  1. Angular推荐approach of parent child interaction

下面的示例 来自 penley chan

@Directive({
selector: '[provide-parent-form]',
providers: [
    {
        provide: ControlContainer,
        useFactory: function (form: NgForm) {
            return form;
        },
        deps: [NgForm]
    }
  ]
})
export class ProvideParentForm {}

用法:在您的组件的根元素中,在 [(ngModel)] 添加指令之前。示例:

<div provide-parent-form> 
   <input name="myInput" [(ngModel)]="myInput"> 
</div>

现在,如果您将表单对象输出到控制台或任何您可以在表单对象的控件 属性 下看到组件的控件。

Angular 没有自动验证所有表单控件和子表单控件的机制,该任务留给开发人员:

  save() {
    this.validateAllFormFields(this.fg);
  }
  ngOnInit() {
    this.fg = new FormGroup({
      name: new FormControl(
        { value: "", disabled: false },
        Validators.required
      ),
      sub: new FormArray([])
    });
  }

  validateAllFormFields(formGroup: FormGroup | FormArray) {
    Object.keys(formGroup.controls).forEach(field => {
      const control = formGroup.get(field);
      if (control instanceof FormControl) {
        control.markAsTouched({ onlySelf: true });
      } else if (control instanceof FormGroup || control instanceof FormArray) {
        this.validateAllFormFields(control);
      }
    });
  }

您可以像这样在 viewProviders 中使用 ControlContainer

control-container.ts

import { Provider, SkipSelf } from '@angular/core';
import { ControlContainer } from '@angular/forms';

export function controlProviderFactory(container: ControlContainer) {
  return container;
}

export const CONTROL_CONTAINER: Provider = {
  provide: ControlContainer,
  useFactory: controlProviderFactory,
  deps: [[new SkipSelf(), ControlContainer]],
};

child.component.ts

import { Component, OnInit, Input } from "@angular/core";
import { FormArray, FormControl, FormGroup, Validators } from "@angular/forms";
import { CONTROL_CONTAINER } from "../control-container";

@Component({
  selector: "app-child",
  templateUrl: "./child.component.html",
  styleUrls: ["./child.component.css"],
  viewProviders: [CONTROL_CONTAINER]
})
export class ChildComponent implements OnInit {
  @Input() public form: FormGroup;

  constructor() {}
  ngOnInit() {}
}

child.component.html

<ng-container formArrayName="subForm">
    <mat-input-container [formGroupName]="0">
    <mat-form-field>
          <input matInput formControlName="subControl">
    </mat-form-field>
    </mat-input-container>
</ng-container>

并在AppComponent的构造函数中初始化:

  constructor (private formBuilder: FormBuilder) {
    this.fg = this.formBuilder.group({
      name: [null, Validators.required],
      subForm: this.formBuilder.array([])
    });

    const control = <FormArray>this.fg.controls['subForm'];

    control.push(this.formBuilder.group({
      subControl: ['', Validators.required]
    }));
  }

出现错误“在 FormArray 中添加字段时提交时不显示 mat-error”。它在 GitHub here.

上有描述

您可以找到基于您的代码的工作示例 here