首页 > 解决方案 > Angular 反应式表单提交不会触发对子组件的验证

问题描述

我有一个 Angular 表单,它由多个FormGroup子表单组成,应该跨越多个组件。它在父组件上初始化并从父组件提交,每个子组件都得到一个FormGroup他们负责的。控件是用 Angular 材质制作的。

问题是,当我提交表单时,验证不起作用。如果提交按钮在子组件内移动,它们就可以正常工作,因此它与我正在验证的表单组位于同一组件中,但这不是我想要实现的目标。

代码示例如下,带有虚拟名称。

父模板

<form [formGroup]="mainForm" (ngSubmit)="submitForm()">
    <button mat-button mat-raised-button color="primary" type="submit">Save</button>
    <first-child [firstChildGroup]="mainForm.get('firstChildGroup')"></first-child>
    <second-child [secondChildGroup]="mainForm.get('secondChildGroup')"></second-child>
</form>

家长 TS

export class ParentComponent implements OnInit {
    mainForm: FormGroup;
    constructor(private fb: FormBuilder) {}

    ngOnInit(): void {
        this.mainForm = this.fb.group({
            firstChildGroup: this.fb.group({
                one: ['', [Validators.required]] // and other controls with other validators
            }),
            secondChildGroup: this.fb.group({...})
        });    
    }
}

子模板

<div [formGroup]="firstChildGroup">
    <mat-form-field appearance="fill">
        <mat-label>First child group <strong class="text-danger">*</strong></mat-label>
        <input matInput formControlName="one">
        <mat-error>
            Required
        </mat-error>
    </mat-form-field>
</div>

儿童 TS:

export class FirstChildComponent {
    @Input() firstChildGroup: FormGroup;
}

因此,回顾一下:ParentComponent将初始化FormGroup元素传递给几个子组件,但是当提交按钮位于父组件上时,验证将不起作用。它必须是。

有什么解决办法吗?也欢迎所有建议。

标签: angularangular-materialangular-reactive-formsangular-validation

解决方案


由于当我们从父组件调用 onSubmit 时,我们在子组件中使用独立的 FormGroup 指令,所以它不会传播到子组件。

我们可以通过使用 FormGroupDirective 创建子表单来克服这个问题,而不是将 formControl 传递给子组件。

<form #fgd="ngForm" [formGroup]="mainForm" (ngSubmit)="submitForm()">
    <button (click)="fgd.onSubmit(null)" mat-button mat-raised-button color="primary" type="submit">Save</button>
    <first-child></first-child>
    <second-child></second-child>
</form>

child.component.ts

@Component({
  selector: 'app-first-child',
  templateUrl: './first-child.component.html',
  styleUrls: ['./first-child.component.css'],
  viewProviders: [{ provide: ControlContainer, useExisting: FormGroupDirective }]
})
export class FirstChildComponent implements OnInit {
   firstChildGroup: FormGroup;

  constructor(private parentForm: FormGroupDirective) { }

  ngOnInit() {
    this.firstChildGroup = this.parentForm.form;
  }

}

child.component.html

<div  formGroupName="firstChildGroup">
    <mat-form-field appearance="fill">
        <mat-label>First child group <strong class="text-danger">*</strong></mat-label>
        <input matInput formControlName="one">
        <mat-error>
            Required
        </mat-error>
    </mat-form-field>  
</div> 

工作示例


推荐阅读