【问题标题】:Reactive form - Cross fields validation (Single mesage based on group field's value)反应式表单 - 跨字段验证(基于组字段值的单个消息)
【发布时间】:2019-11-03 09:55:26
【问题描述】:

我有如下反应形式:

this.newReporterform = this.formBuilder.group({
  rptrTitle: formBuilder.group({
    reporterTitle: new FormControl(),
    reporterTitleNV:new FormControl()
  }, {validator: this.bothEmptyValidator}) ,
  rptrfirstName: formBuilder.group({
    reporterFName: new FormControl(),
    reporterFNameNV:new FormControl()
  }, {validator: this.bothEmptyValidator}) , 
  rptrmiddleName: formBuilder.group({
    reporterMName: new FormControl(),
    reporterMNameNV:new FormControl()
  }, {validator: this.bothEmptyValidator}) ,
  rptrLastName: formBuilder.group({
    reporterLName: new FormControl(),
    reporterLNameNV:new FormControl()
  }, {validator: this.bothEmptyValidator}) ,

});

上面的HTML示例视图如下:

<form [formGroup]="newReporterform"  (ngSubmit)="onSubmit()" >
  <div class="col-sm-12 ">                        
                      <div class="form-group" formGroupName="rptrfirstName" >
                          <span>First Name / Given Name </span>
                          <div class="input-group" >                            
                          <input type="text" class="form-control " [(ngModel)]="reporterFName" formControlName="reporterFName">                       
                          <select class="form-control col-sm-3" style="font-size:13px;"  [(ngModel)]="reporterFNameNV" formControlName="reporterFNameNV">                             
                              <option value="0" >Pls select</option>
                              <option value="1" >Option1</option>
                              <option value="2" >Option2</option>
                              <option value="3" >Option3</option>
                              <option value="4" >Option4</option>                              
                            </select>                            
                      </div>
                      <div class='text-danger' *ngIf="newReporterform.controls.rptrfirstName.controls.hasError('bothEmpty')">
                        Please enter information in one of the above fields.
                  </div>
                   </div>

                  </div>
                  <div class="col-sm-12">                        
                      <div class="form-group" formGroupName="rptrmiddleName">
                          <span>Middle Name </span>
                          <div class="input-group">                            
                          <input type="text" class="form-control " [(ngModel)]="reporterMName" formControlName="reporterMName">                       
                          <select class="form-control col-sm-3" style="font-size:13px;" [(ngModel)]="reporterMNameNV" formControlName="reporterMNameNV">
                              <option value="0">Select</option>
                              <option value="1">MSK</option>
                              <option value="2">ASKU</option>
                              <option value="3">NASK</option>
                              <option value="4">UNK</option>
                            </select>                            
                      </div> 

          <div class='text-danger' *ngIf="newReporterform.controls.rptrmiddleName.controls.hasError('bothEmpty')">
                        Please enter information in one of the above fields.
                  </div>

                      </div>
                  </div>
</form>

请注意 - 我的验证器功能:

 bothEmptyValidator: ValidatorFn = (fg: FormGroup) => { 
    const ValuesArray= Object.values(fg.controls)   
    let field1 = ValuesArray[0].value;
    let field2 = ValuesArray[1].value;    
     field1 === null && field2 === null  ? { bothEmpty: true } : null  
    }

我的验证器功能可以很好地获取表单组内的两个控件的值,例如 rptrfirstName/rptrmiddleName..etc,并且对于主表单的所有此类子表单组都可以正常工作..但是我被卡住了在显示错误“请在上述字段之一中输入信息。”,引发类似_co.newReporterform.controls.rptrfirstName.controls.hasError is not a function...

注意**这是一个常见错误,应在两个连续字段的底部显示。** 以下是字段组的示例显示:

有没有办法实现错误无需提及/进入表单组(两个字段)内的各个控件?(我的意思是,在表单组级别处理)

对此的任何帮助都非常感谢。 提前致谢 ASJ

-----更新------- 表单控件中的表单提交结果值“未定义”。因此验证器消息不会闪现到 UI。

【问题讨论】:

  • 错误是关于formGroup,所以必须是newReporterform.controls.rptrfirstName.hasError('bothEmpty') -remove the "controls"
  • 谢谢...控制台上的错误已解决...但是验证错误不会闪现到 UI...对象的值为“未定义”(图片附加到原始帖子),,,已尝试初始化为reporterFName: new FormControl('')...仍然无法正常工作...
  • 你的代码有几个错误,我写一个回复希望对你有帮助
  • 已合并推荐的代码更改...非常感谢....

标签: angular


【解决方案1】:

为了让验证器将错误发送到 formGroup 你需要实际返回值,我不确定你是否在复制它时遗漏了它,但以防万一,你的代码应该是:

bothEmptyValidator: ValidatorFn = (fg: FormGroup) => { 
  const ValuesArray= Object.values(fg.controls)   
  let field1 = ValuesArray[0].value;
  let field2 = ValuesArray[1].value;    
  return field1 === null && field2 === null  ? { bothEmpty: true } : null; 
}

也就是说,您还需要访问您在调用hasError 方法时分配验证器的formGroup,而不是控制列表。请尝试以下方法:

<div class='text-danger' *ngIf="newReporterform.controls.rptrfirstName.hasError('bothEmpty')">
  Please enter information in one of the above fields.
</div>

请注意,唯一的区别是 hasError 属于 rptrfirstName 而不是 rptrfirstName.controls

【讨论】:

  • 谢谢大卫!...是的,现在错误已解决..但是错误消息没有显示到表单中....执行没有数据的提交会填充表单控件值“未定义”...因此已将初始化执行为 rptrfirstName: formBuilder.group({reporterFName: new FormControl(''), reportFNameNV:new FormControl('') }, {validator: this.bothEmptyValidator}) ...仍然无法将味精发送到前端.我将屏幕截图附加到原始帖子。
  • 我在屏幕截图中看到您正在打印表单的值,您可以打印this.newReporterForm 的值,并检查以下两件事:1. 属性valid 是否等于true ? 2. 如果你进入控制数组,例如 rptrfirstName,这个有效吗? errors 属性是否等于 null?
  • 嗨大卫....检查 1 -> 属性有效等于“真”/检查 2 -> 错误:空。 validatorFn 的问题??....已尝试使用“必需”验证器在 formGroup 中使用单个 fileld 并重复上述检查...属性值正确且错误闪现到 UI...
  • 你的验证器不工作。您是否添加了我在第一条评论中提到的退货声明?否则,可能是您将它们与 null 进行比较,请尝试 undefined,或者只是 return !field &amp;&amp; !field2 ? {bothEmpty: true} : null;,因此您还可以检查空字符串。
  • 它完美地工作,与您修改的返回表达式。非常感谢..!
【解决方案2】:

新手,你的代码有很多错误。

首先,不要使用 [(ngModel)],您使用的是响应式表单。您可以使用新的 FormGroup 而不是 FormBuilder,所以您的表单就像

this.newReporterform = new FormGroup({
  rptrTitle: new FormGroup(
    {
      reporterTitle: new FormControl(),
      reporterTitleNV: new FormControl()
    },
    this.bothEmptyValidator
  ),
  rptrfirstName: new FormGroup(
    {
      reporterFName: new FormControl(),
      reporterFNameNV: new FormControl()
    },
    this.bothEmptyValidator
  ),
  rptrmiddleName: new FormGroup(
    {
      reporterMName: new FormControl(),
      reporterMNameNV: new FormControl()
    },
    this.bothEmptyValidator
  ),
  rptrLastName: new FormGroup(
    {
      e: new FormControl(),
      reporterLNameNV: new FormControl()
    },
    this.bothEmptyValidator
  )
});

和表格一样

<form [formGroup]="newReporterform" (ngSubmit)="onSubmit()">
    <div class="col-sm-12 ">
        <div class="form-group" formGroupName="rptrfirstName">
            <span>First Name / Given Name </span>
            <div class="input-group">
                <input type="text" class="form-control "  formControlName="reporterFName">
                <select class="form-control col-sm-3" style="font-size:13px;"   formControlName="reporterFNameNV">
           <option [ngValue]="null" >Pls select</option>
           <option value="1" >Option1</option>
           <option value="2" >Option2</option>
           <option value="3" >Option3</option>
           <option value="4" >Option4</option>                              
        </select>
            </div>
            <div class='text-danger' *ngIf="newReporterform.get('rptrfirstName').hasError('bothEmpty')">
                Please enter information in one of the above fields.
            </div>
        </div>

    </div>
    <div class="col-sm-12">
        <div class="form-group" formGroupName="rptrmiddleName">
            <span>Middle Name </span>
            <div class="input-group">
                <input type="text" class="form-control " formControlName="reporterMName">
                <select class="form-control col-sm-3" style="font-size:13px;" formControlName="reporterMNameNV">
          <option [ngValue]="null">Select</option>
          <option value="1">MSK</option>
          <option value="2">ASKU</option>
          <option value="3">NASK</option>
          <option value="4">UNK</option>
        </select>
            </div>

            <div class='text-danger' *ngIf="newReporterform.get('rptrmiddleName').hasError('bothEmpty')">
                Please enter information in one of the above fields.
            </div>

        </div>
    </div>
</form>

如果选择此选项,请注意必须使用[ngValue]="null" 分配空值

你可以看到你的forked stackblitz

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-18
    • 2023-03-06
    相关资源
    最近更新 更多