我有一个简单的组件,它实现了反应形式,并设置了7个输入字段select
输入。
我正在尝试在其上应用验证器以强制其中至少一个包含值。
组件:
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
,验证没有存储值。
有什么迹象表明我做错了吗?
更新
不确定这是否重要,但我的输入值是一个数组:
我认为在测试它是否有值时,仍然认为这是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 :(得分:1)
你可以试试这个
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)]],
希望这有帮助
答案 1 :(得分:1)
所以我可能错了,但乍一看,看起来你的验证器已经混淆了。它应该如下:
/**
* 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,换句话说:“我没有发现任何错误”。如果它找到了某个东西,它返回一个具有描述性命名属性的对象,其中一个布尔值进一步描述了该属性的状态,很可能是“真”。这用于触发不同的错误并告知发生错误的形式,以便您可以应用不同的标签和错误消息。
答案 2 :(得分:0)
我的代码看起来有点不同......不确定它是否会改变你的想法:
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