反应式表单 - 将字段标记为已触摸 [英] Reactive Forms - mark fields as touched

查看:20
本文介绍了反应式表单 - 将字段标记为已触摸的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不知道如何将所有表单的字段标记为已触摸.主要问题是,如果我不触摸字段并尝试提交表单 - 未显示验证错误.我的控制器中有那段代码的占位符.
我的想法很简单:

I am having trouble finding out how to mark all form's fields as touched. The main problem is that if I do not touch fields and try to submit form - validation error in not shown up. I have placeholder for that piece of code in my controller.
My idea is simple:

  1. 用户点击提交按钮
  2. 所有字段都标记为已触及
  3. 错误格式化程序重新运行并显示验证错误

如果有人有其他想法如何在提交时显示错误,而不实施新方法 - 请分享它们.谢谢!

If anyone have other idea how to show errors on submit, without implementing new method - please share them. Thanks!

我的简化形式:

<form class="form-horizontal" [formGroup]="form" (ngSubmit)="onSubmit(form.value)">
    <input type="text" id="title" class="form-control" formControlName="title">
    <span class="help-block" *ngIf="formErrors.title">{{ formErrors.title }}</span>
    <button>Submit</button>
</form>

还有我的控制器:

import {Component, OnInit} from '@angular/core';
import {FormGroup, FormBuilder, Validators} from '@angular/forms';

@Component({
  selector   : 'pastebin-root',
  templateUrl: './app.component.html',
  styleUrls  : ['./app.component.css']
})
export class AppComponent implements OnInit {
  form: FormGroup;
  formErrors = {
    'title': ''
  };
  validationMessages = {
    'title': {
      'required': 'Title is required.'
    }
  };

  constructor(private fb: FormBuilder) {
  }

  ngOnInit(): void {
    this.buildForm();
  }

  onSubmit(form: any): void {
    // somehow touch all elements so onValueChanged will generate correct error messages

    this.onValueChanged();
    if (this.form.valid) {
      console.log(form);
    }
  }

  buildForm(): void {
    this.form = this.fb.group({
      'title': ['', Validators.required]
    });
    this.form.valueChanges
      .subscribe(data => this.onValueChanged(data));
  }

  onValueChanged(data?: any) {
    if (!this.form) {
      return;
    }

    const form = this.form;

    for (const field in this.formErrors) {
      if (!this.formErrors.hasOwnProperty(field)) {
        continue;
      }

      // clear previous error message (if any)
      this.formErrors[field] = '';
      const control = form.get(field);
      if (control && control.touched && !control.valid) {
        const messages = this.validationMessages[field];
        for (const key in control.errors) {
          if (!control.errors.hasOwnProperty(key)) {
            continue;
          }
          this.formErrors[field] += messages[key] + ' ';
        }
      }
    }
  }
}

推荐答案

以下函数递归地遍历表单组中的控件并轻轻触摸它们.由于控件字段是一个对象,因此代码对表单组的控件字段调用 Object.values().

The following function recurses through controls in a form group and gently touches them. Because the controls field is an object, the code call Object.values() on the form group's control field.

  /**
   * Marks all controls in a form group as touched
   * @param formGroup - The form group to touch
   */
  private markFormGroupTouched(formGroup: FormGroup) {
    (<any>Object).values(formGroup.controls).forEach(control => {
      control.markAsTouched();

      if (control.controls) {
        this.markFormGroupTouched(control);
      }
    });
  }

这篇关于反应式表单 - 将字段标记为已触摸的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆