无法在角度的嵌套表单组上读取未定义的属性“ hasError”

时间:2019-09-04 07:36:54

标签: angular angular-reactive-forms angular-forms

为嵌套组创建验证时,始终出现“无法读取未定义的属性'hasError'的错误”错误。在主要组上,我没有问题,但是如果它在嵌套表单组上,那就是问题所在。请在下面查看我的代码:

<form
    [formGroup]="form"
    (ngSubmit)="onSubmit(form)"
    class="border border-light p-5"
  >
    <div class="form-group">
      <input
        type="text"
        placeholder="Plaza Name"
        formControlName="name"
        id="name"
        class="form-control mb-4"
        mdbInput
        required
      />
      <span
        *ngIf="formHasError('name', 'required') && isSubmitted"
        style="color: red;"
      >
        Plaza Name is required
      </span>
    </div>
    <div class="form-group">
      <input
        type="number"
        placeholder="Plaza Code"
        formControlName="code"
        id="code"
        class="form-control mb-4"
        mdbInput
        required
      />
      <span
        *ngIf="formHasError('code', 'required') && isSubmitted"
        style="color: red;"
      >
        Plaza code is required
      </span>
    </div>

    <div formGroupName="lanes">
      <div class="form-group">
        <input
          type="number"
          placeholder="Lane Number"
          formControlName="number"
          id="number"
          class="form-control mb-4"
          mdbInput
          required
        />
        <span
          *ngIf="formHasError('lanes.number', 'required') && isSubmitted"
          style="color: red;"
        >
          Lane number is required
        </span>
      </div>
      <div class="form-group">
        <select
          formControlName="type"
          id="type"
          class="browser-default custom-select mb-4"
          mdbInput
          required
        >
          <option *ngFor="let type of typeSelect" [value]="type.label">{{
            type.label
          }}</option>
        </select>
        <!-- <span
          *ngIf="formHasError('lanes.type', 'required') && isSubmitted"
          style="color: red;"
        >
          Select a lane type
        </span> -->
      </div>
    </div>
    <button
      mdbBtn
      color="info"
      outline="true"
      block="true"
      class="z-depth-0 my-4 waves-effect"
      mdbWavesEffect
      type="submit"
    >
      Send
    </button>
 </form>

这是在ts文件中

createForm() {
    this.form =  this.fb.group({
      name: [null, Validators.required],
      code: [null, Validators.required],
      lanes: this.fb.group({
        number: [null, Validators.required],
        type: [null, Validators.required]
      })
    });
}

formHasError(controlName: string, errorName: string) {
   return this.form.controls[controlName].hasError(errorName);
}

您能告诉我如何正确执行此操作吗?谢谢你。

4 个答案:

答案 0 :(得分:2)

个人;我选择了这样的解决方案,无需使用额外的功能即可更轻松,更清晰

<form
    [formGroup]="form"
    (ngSubmit)="onSubmit(form)"
    class="border border-light p-5"
  >
    <div class="form-group">
      <input
        type="text"
        placeholder="Plaza Name"
        formControlName="name"
        id="name"
        class="form-control mb-4"
        mdbInput
        required
      />
      <span
        *ngIf="form.name.hasError('required') && isSubmitted"
        style="color: red;"
      >
        Plaza Name is required
      </span>
    </div>
    <div class="form-group">
      <input
        type="number"
        placeholder="Plaza Code"
        formControlName="code"
        id="code"
        class="form-control mb-4"
        mdbInput
        required
      />
      <span
        *ngIf="form.code.hasError('required') && isSubmitted"
        style="color: red;"
      >
        Plaza code is required
      </span>
    </div>

    <div formGroupName="lanes">
      <div class="form-group">
        <input
          type="number"
          placeholder="Lane Number"
          formControlName="number"
          id="number"
          class="form-control mb-4"
          mdbInput
          required
        />
        <span
          *ngIf="form.lanes.number.hasError('required') && isSubmitted"
          style="color: red;"
        >
          Lane number is required
        </span>
      </div>
      <div class="form-group">
        <select
          formControlName="type"
          id="type"
          class="browser-default custom-select mb-4"
          mdbInput
          required
        >
          <option *ngFor="let type of typeSelect" [value]="type.label">{{
            type.label
          }}</option>
        </select>
        <!-- <span
          *ngIf="formHasError('lanes.type', 'required') && isSubmitted"
          style="color: red;"
        >
          Select a lane type
        </span> -->
      </div>
    </div>
    <button
      mdbBtn
      color="info"
      outline="true"
      block="true"
      class="z-depth-0 my-4 waves-effect"
      mdbWavesEffect
      type="submit"
    >
      Send
    </button>
 </form>

答案 1 :(得分:2)

stackblitz

formHasError(controlName: string, errorName: string) {
    const control=this.form.get(controlName);
    return control?control.hasError(errorName):false;
  }

答案 2 :(得分:1)

因为您的主表单中有一个表单组(车道),所以如果您调用this.form.controls['lanes'],它将返回一个带有控件而不是formcontrol的formGroup,因此您应该在函数中考虑子表单,并且formHasError应该是:

if(this.form.controls[controlName].controls) {
        return this.form.controls[controlName]['controls'].hasError(errorName);
    } else {
        return this.form.controls[controlName].hasError(errorName);
    }

答案 3 :(得分:0)

您只需要使用get方法

formHasError(controlName: string, errorName: string) : boolean {
   return this.form.get(controlName).hasError(errorName);
}
  

get方法在给定控件名称或路径的情况下检索子控件。

stackblitz demo ??