Angular 在提交时验证子组件

Angular 在提交时验证子组件,angular,angular-reactive-forms,Angular,Angular Reactive Forms,我一直在网上查,找不到任何答案 我用的是角度10和反应形式 这是我的问题:单击submit按钮会在按钮级别触发表单的有效性,但不会在子组件级别触发 这是你的电话号码 如果在本例中按“保存”,您将只看到第一个输入触发验证并变为红色,而其他输入需要手动单击。我有一个formGroup和两个控件,一个是FormControl,另一个是FormArray。我将主formGroup传递给子组件,并在formArray中按1formGroup,该formGroup有一个formControl。基本上,我在叶

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

我用的是角度10和反应形式

这是我的问题:单击submit按钮会在按钮级别触发表单的有效性,但不会在子组件级别触发

这是你的电话号码

如果在本例中按“保存”,您将只看到第一个输入触发验证并变为红色,而其他输入需要手动单击。我有一个
formGroup
和两个控件,一个是
FormControl
,另一个是
FormArray
。我将主
formGroup
传递给子组件,并在
formArray
中按1
formGroup
,该
formGroup
有一个
formControl
。基本上,我在叶上有两个
FormControl
。如果这不合理,请告诉我


因此,我希望检查所有元素的有效性,不管它是否在子组件中。

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

  • 这就像一个交钥匙一样有效,我喜欢这种方法,因为它通过扩展4个类/选项中的一个来打破复杂性

  • 推荐角度
  • 下面是来自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
    ,如下所示:

    controlcontainer.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]],
    };
    
    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.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]],
    };
    
    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>
    
    有一个错误“在FormArray中添加字段时,提交时不显示mat error”。它在GitHub上有描述


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

    谢谢您的回答,但我已经看完了这个示例,您的示例使用了
    ngForm
    我使用了被动形式。有什么想法吗?啊,我明白了,我明天会发布一些东西,但同时这里有一个例子。这里有icontrolAccessorValidator。。。不记得那是关键谢谢你我会检查并等待你的回答谢谢你的回答,你觉得@transformer的
    controlValueAccessor
    方法怎么样?如果子窗体有直接的FormControl(即没有深度嵌套的控件),自定义controlValueAccessor方法会起作用,我提供的解决方案是通用的usecaseok@karavanjo似乎是最好的解决方案,尽管我并不完全理解。再次感谢您的帮助谢谢这太棒了!您能否对控件容器对象添加更多的解释。我将实现它,并将其标记为已回答,如果这项工作我做了一些更改,以便在子组件中初始化formArray,并且成功了。伟大的有人能解释投票失败的原因吗