Angular2反应形式验证

Angular2反应形式验证

问题描述:

我有一个简单的组件,它实现反应形式并设置7个输入字段,它们是select输入。Angular2反应形式验证

我想申请一个验证它迫使他们中的至少一个包含一个值。

组件:

renderForm() { 
     this.importForm = this.fb.group({ 
      costCenter: [], 
      area: [], 
      silo: [], 
      department: [], 
      location: [], 
      segment: [], 
      role: [] 
     }, 
      { 
       validator: (formGroup: FormGroup) => { 
        return this.validateFilter(formGroup); 
       } 
      }); 
    } 

    /** 
    * Checks to see that at least one of the filter 
    * options have been filled out prior to searching 
    * for employees. 
    * 
    * @param formGroup 
    */ 
    validateFilter(formgroup: FormGroup) { 
     if (formgroup.controls["costCenter"].value || 
      formgroup.controls["area"].value || 
      formgroup.controls["silo"].value || 
      formgroup.controls["department"].value || 
      formgroup.controls["location"].value || 
      formgroup.controls["segment"].value || 
      formgroup.controls["role"].value 
     ) { 
      return { validateFilter: true }; 
     } else { 
      return null; 
     } 
    } 

当我提交我的形式的检查form本身,它口口声声说其有效的,即使没有任何的输入已经被填写。

当我看个人的形式控制值,它们被显示为null,验证没有值已存储。

任何明显的我做错了?

更新:

不知道这事,但我输入的值是一个数组:

enter image description here

我会认为这仍然被认为是true测试时看看它是否有价值?

更新2: 这是我的HTML代码片段。这段代码对于每个下拉菜单都是相同的,只是引用不同的函数来填充它。

<tr> 
       <td class="col-md-2 strong">Area</td> 
       <td> 
        <div class="form-group"> 
         <ng-select formControlName="area" [allowClear]="true" [multiple]="true" [items]="getAreas()" placeholder="Select one or more Areas"> 
         </ng-select> 
        </div> 
       </td> 
      </tr> 

更新3:

按照要求,这里是完整的HTML模板。

<tbody> 
      <tr> 
       <td class="col-md-2 strong">Cost Center</td> 
       <td> 
        <div class="form-group"> 
         <ng-select formControlName="costCenter" [allowClear]="true" [multiple]="true" [items]="getCostCenters()" placeholder="Select one or more Cost Centers"> 
         </ng-select> 
        </div> 
       </td> 
      </tr> 
      <tr> 
       <td class="col-md-2 strong">Area</td> 
       <td> 
        <div class="form-group"> 
         <ng-select formControlName="area" name="area" [allowClear]="true" [multiple]="true" [items]="getAreas()" placeholder="Select one or more Areas"> 
         </ng-select> 
        </div> 
       </td> 
      </tr> 
      <tr> 
       <td class="col-md-2 strong">Silo</td> 
       <td> 
        <div class="form-group"> 
         <ng-select formControlName="silo" name="silo" [allowClear]="true" [multiple]="true" [items]="getSilos()" placeholder="Select one or more Silos"> 
         </ng-select> 
        </div> 
       </td> 
      </tr> 
      <tr> 
       <td class="col-md-2 strong">Department</td> 
       <td> 
        <div class="form-group"> 
         <ng-select formControlName="department" name="department" [allowClear]="true" [multiple]="true" [items]="getDepartments()" placeholder="Select one or more Departments"> 
         </ng-select> 
        </div> 
       </td> 
      </tr> 
      <tr> 
       <td class="col-md-2 strong">Location</td> 
       <td> 
        <div class="form-group"> 
         <ng-select formControlName="location" name="location" [allowClear]="true" [multiple]="true" [items]="getLocations()" placeholder="Select one or more Locations"> 
         </ng-select> 
        </div> 
       </td> 
      </tr> 
      <tr> 
       <td class="col-md-2 strong">Segment</td> 
       <td> 
        <div class="form-group"> 
         <ng-select formControlName="segment" name="segment" [allowClear]="true" [multiple]="true" [items]="getSegments()" placeholder="Select one or more Segments"> 
         </ng-select> 
        </div> 
       </td> 
      </tr> 
      <tr> 
       <td class="col-md-2 strong">Role</td> 
       <td> 
        <div class="form-group"> 
         <ng-select formControlName="role" name="role" [allowClear]="true" [multiple]="true" [items]="getRoles()" placeholder="Select one or more Roles"> 
         </ng-select> 
        </div> 
       </td> 
      </tr> 
     </tbody> 

更新4:

作为一个测试,我评论了所有的验证逻辑的和刚刚返回return { validFilter: true };期待它告诉我的形式,它的valid。但是,情况并非如此,表格仍为invalid

似乎在其他地方可能存在潜在的问题?

+0

这将是无效的,因为部门,地点等是空的。你能展示你的模板吗? – brijmcq

+0

@brijmcq我在问题中添加了一个HTML代码片段。 – SBB

+0

@brijmcq - 我将'name ='属性添加到每个元素,导致相同的问题。 – SBB

所以我可能是错的,但第一眼看上去你有验证混合起来。它应该是以下几点:

/** 
* Checks to see that at least one of the filter 
* options have been filled out prior to searching 
* for employees. 
* 
* @param formGroup 
*/ 
validateFilter(formgroup: FormGroup) { 
    if (formgroup.controls["costCenter"].value || 
     formgroup.controls["area"].value || 
     formgroup.controls["silo"].value || 
     formgroup.controls["department"].value || 
     formgroup.controls["location"].value || 
     formgroup.controls["segment"].value || 
     formgroup.controls["role"].value 
    ) { 
     return null 
    } else { 
     return { noFilterOptionsSet: true }; 
    } 
} 

的方式验证器的工作是一个“有效”验证返回NULL,换句话说:“我没有发现任何错误。”如果它发现它返回一个具有描述性命名属性的对象,其布尔值进一步描述该属性的状态,最有可能是“真”。这用于触发不同的错误并通知发生错误的形式,以便您可以应用不同的标签和错误消息。

+0

我认为这就是它!快速测试表明,当我为单个输入选择一个值时,它通过了验证。但是,当我删除该值时,看起来像我的表单将该值保留为空数组而不是null。 'role:Array(0)'vs当它作为'role:null'开始时。我只需要查看是否可以在删除时将其重置为空,然后在删除后验证应重置为无效。很快就会接受这个答案。 – SBB

+0

您可能需要有一个“清除”按钮,使用控件上的setValue方法将它们返回到null状态。 – joshrathke

+0

我懂了。我只是将我的表单控件设置为一个空数组'costCenter:[[]]',然后在我的验证器中,我做了'formgroup.controls [“costCenter”] .value.length'。 不错的工作捕捉:) – SBB

你可以试试这个

this.importForm = this.fb.group({ 
      costCenter: ['', [Validators.required], 
      area: ['', [Validators.required], 
      silo: ['', [Validators.required], 
      department: ['', [Validators.required], 
      location: ['', [Validators.required], 
      segment: ['', [Validators.required], 
      role: ['', [Validators.required] 
     }); 

这将使您的形式与'与需要验证默认值。为什么验证是在阵列的原因是因为你还可以添加多个验证这样

department: ['', [Validators.required, Validators.minLength(3)]], 

希望这有助于

+0

我给了这个尝试,现在即使当我为任何输入选择一个值时,表单也是“无效的”。作为一项测试,我甚至试图为所有输入选择一个值,并没有什么不同。 – SBB

我的代码看起来有点不同...不知道这是否会改变你的东西:

validateFilter(formgroup: FormGroup) { 
    if (formgroup.get("costCenter").value || 
     formgroup.get("area").value || 
     formgroup.get("silo").value || 
     formgroup.get("department").value || 
     formgroup.get("location").value || 
     formgroup.get("segment").value || 
     formgroup.get("role").value 
    ) { 
     return { 'validateFilter': true }; 
    } else { 
     return null; 
    } 
} 
  • 在return语句,返回值是一个字符串和一个布尔值,所以我封闭它引号。

  • 我也使用.get而不是.controls,但这应该不重要。

我有一个自定义组验证的工作示例这里引用是否有帮助:https://github.com/DeborahK/Angular2-ReactiveForms/tree/master/Demo-Final-Updated

+0

我试了一下,遇到了同样的问题。即使在我选择输入时,整个表单也是无效的。我更新了我原来的问题,以确保我的值是一个数组没有问题。这仍然会测试为'真?'我正在使用插件'ng-select',它允许我从下拉列表中选择多个值,因此最终输出是一个数组。 – SBB

+0

所以它听起来像每个输入元素,然后*有一个值是数组。你有没有尝试过检查数组长度,而不是检查null? 'formgroup.get(“costCenter”).value.length' – DeborahK

+0

好的调用,我尝试在那里添加'.length'检查,但是,它导致了同样的无效格式。 – SBB