Angular2 反应式表单验证

Angular2 Reactive Forms Validation

我有一个简单的组件,它实现了响应式表单并设置了 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 本身时,它一直说它有效,即使 none 的输入已填写。

当我查看单个表单控件值时,它们显示为 null,验证没有存储值。

有什么值得注意的地方我做错了吗?

更新:

不确定这是否重要,但我输入的值是一个数组:

我会认为这还算是true在测试看有没有值的时候?

更新二: 这是我的 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>

更新四:

作为测试,我注释掉了所有验证逻辑并返回 return { validFilter: true };,希望它告诉我的表单它 valid。然而,情况并非如此,表格仍然是 invalid.

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

你可以试试这个

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)]],

希望对您有所帮助

我的代码看起来有点不同...不确定它是否会为您带来改变:

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语句中,return值是一个字符串和一个布尔值,所以我用引号括起来了。

  • 我也使用了 .get 而不是 .controls,但这应该无关紧要。

如果有帮助,我这里有一个自定义组验证器的工作示例供参考:https://github.com/DeborahK/Angular2-ReactiveForms/tree/master/Demo-Final-Updated

所以我可能是错的,但乍一看你似乎混淆了验证器。应该是这样的:

/**
 * 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 };
    }
}

验证器的工作方式是 "valid" 验证器 returns null,换句话说:"I didn't find anything wrong"。如果它找到某个东西,它 returns 一个具有描述性名称 属性 的对象,其布尔值进一步描述 属性 的状态,很可能 "true"。这用于触发不同的错误并告知发生错误的形式,以便您可以应用不同的标签和错误消息。