Angular 2 Reactive Forms会在提交时触发验证

arv*_*hts 32 angular2-forms angular

是否有一种方法可以在提交时触发所有被动形式的验证器,而不仅仅是"脏"和"触摸"事件?

这样做的原因是我们有一个非常大的表单,它不表示是否需要字段,用户可能会错过一些必需的控件,因此在提交时,预计会丢失所有错误的字段最终用户将被显示.

我已经尝试通过使用标记将表单标记为"触摸"

FormGroup.markAsTouched(true);
Run Code Online (Sandbox Code Playgroud)

它工作,所以我也尝试将其标记为"脏"

FormGroup.markAsDirty(true);
Run Code Online (Sandbox Code Playgroud)

但是班级的css仍然是"原始的",

有没有办法从组件手动触发它,我试着谷歌搜索无济于事,谢谢你提前!

UPDATE

我已经通过迭代FormGroup.controls并将其标记为"脏"来完成它,但是有一种"标准"方法来执行此操作.

AJT*_*T82 18

这可以通过此处提供的示例实现,您可以其中使用NgForm指令:

<form [formGroup]="heroForm" #formDir="ngForm">
Run Code Online (Sandbox Code Playgroud)

然后在验证消息中检查表单是否已提交:

<small *ngIf="heroForm.hasError('required', 'formCtrlName') && formDir.submitted">
  Required!
</small>
Run Code Online (Sandbox Code Playgroud)

  • 该解决方案将经典模板驱动的表单技术与新的反应式表单技术相结合,使其可能不必要地低效,并且因为需要了解这两种技术而令人困惑. (4认同)

San*_*ile 16

有多种方法可以解决问题.如果你有嵌套的表单组,@ Splaktar的答案将不起作用.所以,这是适用于嵌套表单组的解决方案.

解决方案1:遍历所有表单组和表单控件,并以编程方式触摸它们以触发验证.

模板代码:

<form [formGroup]="myForm" (ngSubmit)="onSubmit()" novalidate>
...
<button type="submit" class="btn btn-success">Save</button>
</form>
Run Code Online (Sandbox Code Playgroud)

component.ts代码:

    onSubmit() {
        if (this.myForm.valid) {
            // save data
        } else {
            this.validateAllFields(this.myForm); 
        }
    }

validateAllFields(formGroup: FormGroup) {         
        Object.keys(formGroup.controls).forEach(field => {  
            const control = formGroup.get(field);            
            if (control instanceof FormControl) {             
                control.markAsTouched({ onlySelf: true });
            } else if (control instanceof FormGroup) {        
                this.validateAllFields(control);  
            }
        });
    }
Run Code Online (Sandbox Code Playgroud)

解决方案2:使用变量检查表单是否已提交.仅供参考: ngForm的提交字段目前正在测试中,将包含在未来的Angular版本中.因此不需要创建自己的变量.

component.ts代码

private formSubmitAttempt: boolean;

onSubmit() {
        this.formSubmitAttempt = true;
        if (this.myForm.valid) {
            console.log('form submitted');
        }
   }
Run Code Online (Sandbox Code Playgroud)

模板代码:

<form [formGroup]="myForm" (ngSubmit)="onSubmit()" novalidate>
    <div class="form-group">
        <label class="center-block">
            Name:
            <input class="form-control" formControlName="name">
        </label>
        <div class="alert alert-danger" *ngIf="myForm.get('name').hasError('required') && formSubmitAttempt">
            Name is required
        </div>
        ...
</form>
Run Code Online (Sandbox Code Playgroud)


Mat*_*ira 14

几个月后回来,我在这里分享基于所有评论的改进版本,仅供记录:

markAsTouched(group: FormGroup | FormArray) {
  group.markAsTouched({ onlySelf: true });

  Object.keys(group.controls).map((field) => {
    const control = group.get(field);
    if (control instanceof FormControl) {
      control.markAsTouched({ onlySelf: true });
    } else if (control instanceof FormGroup) {
      this.markAsTouched(control);
    }
  });
}
Run Code Online (Sandbox Code Playgroud)

希望它会有用!


Spl*_*tar 5

这可以通过完成markAsTouched()。在PR #26812合并之前,您可以使用

function markAllAsTouched(group: AbstractControl) {
  group.markAsTouched({onlySelf: true});
  group._forEachChild((control: AbstractControl) => markAllAsTouched(control));
}
Run Code Online (Sandbox Code Playgroud)

您可以在源代码中找到更多信息。