【问题标题】:How to get Form properties(form.submitted) from FormControl?如何从 FormControl 获取表单属性(form.submitted)?
【发布时间】:2020-05-06 05:32:47
【问题描述】:

我创建了一个通用组件来显示表单验证错误消息。如下:

import { Component, OnInit, Input } from '@angular/core';
import { FormControl } from '@angular/forms';

@Component({
  selector: 'app-err-msg',
  template: `<div class="input-error" *ngIf="errorMessage !== null">{{errorMessage}}</div>`,
  styleUrls: ['./err-msg.component.css']
})
export class ErrMsgComponent implements OnInit {

  @Input() control: FormControl;
  @Input() fieldName: FormControl;
  isInvalidMsg = ' is invalid';

  constructor() { }

  get errorMessage() {
    for (const propertyName in this.control.errors) {
      if (this.control.errors.hasOwnProperty(propertyName) && this.control.touched) {
        return this.getValidatorErrorMessage(propertyName, this.control.errors[propertyName]);
      }
    }
    return null;
  }

  getValidatorErrorMessage(validatorName: string, validatorValue?: any) {
    const config = {
      'required': this.fieldName + ' is required',
      'appPhoneValidate': this.fieldName + this.isInvalidMsg,
      'appEmailValidate': this.fieldName + this.isInvalidMsg,
      'appPasswordValidate': this.fieldName + ' must containt 8 characters, capital letters, lowercase, numbers and special character.',
      'minlength': `minnimum length ${validatorValue.requiredLength}`,
      'min': `minumum value ${validatorValue.min}`,
      'max': `maximum value ${validatorValue.max}`,
      'matchPassword': this.fieldName + ' is mismatched',
      'appEqualvalidate': this.fieldName + ' is mismatched',
      'appWebValidate': this.fieldName + this.isInvalidMsg,
      'appTimeCheckValidate': this.fieldName + this.isInvalidMsg,
    };

    return config[validatorName];
  }

  ngOnInit() {
  }

}

我已经将此组件用作:

<select
  name="timezone"
  id="timezoneList"
  #timezone="ngModel"
  class="form-control text-black"
  [(ngModel)]="caseDetail.timezoneId"
  required
>
  <option [ngValue]="null" disabled>Select Timezone</option>
  <option [ngValue]="timezone?.id" *ngFor="let timezone of timezoneList">{{ timezone?.timezoneWithOffset }}</option>
</select>
<app-err-msg [control]="timezone" fieldName="Timezone"></app-err-msg>

在这里我遇到问题,当我单击表单中的取消按钮时,第一次单击会显示验证错误,当我第二次单击取消按钮时,表单提交被取消。这是因为我使用过:this.control.touched

要解决这个问题,我可以使用if(form.submitted === true),但问题是如何从单个 FormControl 获取 Form 属性,因为我只是传递控件引用而不是 Form 引用。 有什么方法可以获取控件父窗体的属性吗?

【问题讨论】:

  • 你想访问 app-err-msg 组件中的父表单吗?

标签: angular validation angular-forms angular-validation


【解决方案1】:

我认为问题在于您忘记在取消中给出 type='button'

<button type='button' (click)="....">Cancel</button>

无论如何,如果使用[control]="timezone",控件就不是FormControl,是NgControl

@Input() control: NgControl;

您可以使用访问表单

this.control.control.parent

但表单中没有“已提交”属性

【讨论】:

  • 是的,但是,当我 console.log 时,它确实显示在 control._parent.submitted: true,但是当我尝试访问 component.ts 中的 _parent 时,它显示 undefined
【解决方案2】:

如果你想使用提交的属性,那么你可以使用NgFormdirective

这是一个例子。我们有一个包含表单的组件:

@Component({
  selector: "my-app",
  template: `
    <form [formGroup]="fg" (submit)="onSubmit()" #personForm="ngForm">
      <input type="text" formControlName="name" placeholder="name" /> <br />
      <input type="text" formControlName="email" placeholder="email" />
      <form-status
        controlName="email"
        [submitted]="personForm.submitted"
      ></form-status>
      <button>Submit</button>
    </form>
  `
})
export class AppComponent {
  public fg: FormGroup;

  // @ViewChild("personForm", { static: true }) private personForm: NgForm;

  constructor(private fb: FormBuilder) {}

  ngOnInit() {
    this.fg = this.fb.group({
      name: [""],
      email: [""]
    });
  }

  public onSubmit() {
    // console.log("submitted", this.personForm.submitted);
  }
}

我们有一个显示表单状态的组件:

@Component({
  selector: "form-status",
  template: `
    <h2>form submitted: {{ submitted }}</h2>
  `
})
export class FormStatusComponent {
  @Input() public submitted = false;
}

我们使用@Input 装饰器从父级获取提交的值。

【讨论】:

  • 我也同意@Eliseo 的回答——你可以给你的按钮一个类型。
  • 我可以使用表单来完成,但问题是,我有一个通用组件来显示我无法访问表单的验证消息。
  • @FaizanSaiyed 您能否分享一些额外的代码,以便我完全理解您的意思?从您的原始帖子中,您使用了一个我认为会嵌套在表单中的选择元素。
猜你喜欢
  • 2018-01-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-31
  • 1970-01-01
相关资源
最近更新 更多