【问题标题】:Nested form validation in angular角度中的嵌套表单验证
【发布时间】:2021-11-16 13:46:07
【问题描述】:

Stackblitz https://stackblitz.com/edit/angular-mh4cox?embed=1&file=src/app/app.component.html

如何在嵌套表单上正确显示错误消息? 验证工作顺便说一句

我在这里尝试了很多方法,但没有任何运气。

我希望它使用 ngIF 在 html 上显示错误消息(... invalid && ... added )

构造函数

    constructor(private fb: FormBuilder,private http:HttpClient,private requestService:RequestService) {
    this.myForm = this.fb.group({
      id:[""],
      areaOfInterest: new FormControl("",Validators.required),
      status: new FormControl("",Validators.required),
      startDate: new FormControl("",Validators.required),
      endDate: new FormControl("",Validators.required),
      description: new FormControl("",Validators.required),
      notes: new FormControl("",Validators.required),
      createdBy:"",
      updatedBy:"",
      resourceDTOS: this.fb.array([]),
    });
    console.log(this.myForm);
    this.getOneRequest(localStorage.getItem('requestId'));
  }

这是嵌套资源,在这种情况下是 FormArray

addNewResourceDTOS() {
    this.control = <FormArray>this.myForm.controls.resourceDTOS;
    this.control.push(
        this.fb.group({
          seniority: this.fb.control(null,Validators.required),
          skillDTOS: this.fb.array([this.fb.group({
            skill: '' //i dont validate it here
          })]),
          resourceNotes: this.fb.control(null,Validators.required),
        })
    );
  }

数组技能DTOS

addNewResourceSkill(control) {
    control.push(
        this.fb.group({
          skill: new FormControl("",Validators.required),
        }))
  }

这就是我验证一些主要表单变量的方式

  get description() {
    return this.myForm.get('description');
  }
  get notes() {

    return this.myForm.get('notes');
  }

示例 html“注释”

<small *ngIf="notes.invalid && notes.touched" class="text-danger">Please enter notes!</small>

看起来像这样

 data = {
    areaOfInterest:"",
    notes:"",

    resourceDTOS: [
      {
        seniority: "",
        skillDTOS: [
          {
            skill: "",
          }
        ],
        resourceNotes:""
      }
    ]
  }

是否也可以至少验证资历/资源说明(或最好的技能)?

【问题讨论】:

  • 对不起,描述不清楚。从您的代码中,我看到验证完全正确。验证适用于资历、resourceNotes 和技能字段(不包括第一项技能)。
  • 但我的目标是在无效时显示错误消息。可能吗?与主要的表单变量一样,例如描述

标签: angular


【解决方案1】:

在您的控制器中,您可以定义一个新方法,该方法将根据特定字段及其祖先索引检查特定字段的有效性。以下是技能领域的示例:

component.ts

  isSkillValid(resourceDTOSIndex: number, skillIndex: number): boolean {
    const resourceDTOSGroup = this.myForm.controls.resourceDTOS as FormGroup;
    const skillDTOSGroup =  resourceDTOSGroup.controls[resourceDTOSIndex] as FormGroup;
    const skillDTOS =  skillDTOSGroup.controls.skillDTOS as FormGroup;

    return skillDTOS.controls[skillIndex].valid;
  }; 

component.html

<input
  formControlName="skill"
  class="form-control"
  style="margin-right:5px;"
  type="text"
  placeholder="Enter skill"
  id="skill"
  name="skill"
  aria-label="button1"
  aria-describedby="button1"
/>

<div *ngIf="!isSkillValid(i, j)">
  The skill field has no valid value
</div>

附言

我真的建议你重构组件并将其拆分成更小的部分,因为它已经很难阅读和操作。

【讨论】:

  • 请注意,此函数将在每次更改检测时调用,并且会影响性​​能。我对 ngFor 循环中的函数特别小心。有时会遇到“无限”循环(技术上不是),因此请注意这样做的副作用。
【解决方案2】:

您可以使用hasError() 简单地访问验证器。因此,只需针对您想要的表单控件,通常由 myFormgroup.get('formcontrolName')... 访问因此,如果您迭代 skill,您可以从您为每个循环声明的定义的 lines 访问当前表单控件:

<div *ngFor="let lines of resource.get('skillDTOS').controls; let j=index">
  <div [formGroupName]="j">
    <input formControlName="skill"/>
    <div *ngIf="lines.get('skill').touched">
      <small *ngIf="lines.get('skill').hasError('required')">REQUIRED</small>
    </div>
  </div>
</div>

【讨论】:

    猜你喜欢
    • 2020-06-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-10
    • 1970-01-01
    • 1970-01-01
    • 2019-05-01
    相关资源
    最近更新 更多