Angular2-反应型性质

Angular2-反应型性质,angular,typescript,angular-reactive-forms,Angular,Typescript,Angular Reactive Forms,我有一个为我的组件生成的反应式表单。用户可以选择使用大约5个可选的选择输入,并从中选择标准 我试图实现一些错误消息,但不能完全弄清楚 请选择一条数据进行筛选。 既然所有字段都是选项,但至少有一个是必需的,那么在显示无效消息之前,我如何检查其中一个字段是否被触摸过 组件: /** * Render the form in the UI to allow * * @memberof FilterSearchComponent */ renderForm() { this.import

我有一个为我的组件生成的反应式表单。用户可以选择使用大约5个可选的选择输入,并从中选择标准

我试图实现一些错误消息,但不能完全弄清楚

请选择一条数据进行筛选。

既然所有字段都是选项,但至少有一个是必需的,那么在显示无效消息之前,我如何检查其中一个字段是否被触摸过

组件:

/**
 * Render the form in the UI to allow
 *
 * @memberof FilterSearchComponent
 */
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.length ||
        formgroup.controls["area"].value.length ||
        formgroup.controls["silo"].value.length ||
        formgroup.controls["department"].value.length ||
        formgroup.controls["location"].value.length ||
        formgroup.controls["segment"].value.length ||
        formgroup.controls["role"].value.length
    ) {
        return null;
    } else {
        return { noFilterOptions: true };
    }
}
如果可以的话,我真的不想对HTML中的每个控件都执行
|
语句


是否有其他方法可以查看我表单中的任何输入是否已被触动,而不是指定我要单独查看的输入?

这里的内容应该可以:

<span *ngIf="importForm.invalid && importForm.touched" class="help-block text-danger">Please select one piece of data to filter by.</span>
请选择一条数据进行筛选。
如果已触摸窗体上的任何控件,则应设置窗体的touch属性。我想它不起作用了吧?它怎么不起作用

触摸->用户输入并离开输入元素。它没有说明用户是否在输入元素中输入了内容

如果您想知道用户是否更新了其中一个输入元素的值,请使用dirty:

<span *ngIf="importForm.invalid && importForm.dirty" 
      class="help-block text-danger">
   Please select one piece of data to filter by.
</span>

请选择一条数据进行筛选。

在这里,我想删除自定义验证器,因为它现在已经存在。它将在您的表单发生任何事情时被激发,我假设它的值比选择的值更多。这会经常引起不必要的火灾

相反,我会听
单击
事件,或类似的内容。下面的示例可能需要进一步改进(?),但如果您选择以下方法,至少您可以使用一些东西

在这里,我假设您不需要对表单中的所有
select
使用数组,而只需要捕获一个值,而单个
FormControl
可以:

this.importForm=this.fb.group({
选项:this.fb.group({
成本中心:[''],
面积:['']
})
});
在构建表单之后,我喜欢将不同的控件存储到变量中,以避免带有属性路径的冗长代码。我将迭代formgroup
optionals
中的对象属性,将其存储在数组中,然后我们可以检查是否至少设置了一个值:

this.optionalCtrl=this.importForm.controls.optionals
在模板中,您需要分别为所有选择设置单击事件


然后,在
checkOptionals
中,将迭代formgroup
optionals
中的对象属性,并检查至少一个属性是否具有空字符串以外的值。基于此,我们为formgroup设置一个自定义错误,或者清除它

checkOptionals(){
for(输入this.optionalCtrl.controls){
if(this.optionalCtrl.controls[key].value!=''){
this.optionalCtrl.clearValidators()
//this.optionalCtrl.updateValueAndValidity()文件
打破
}否则{
this.optionalCtrl.setErrors({“noFilterOptions”:true})
}
}
} }

设置错误后,可能需要调用
updateValueAndValidity
。然后,在模板中,您只需在真实情况下显示此错误:


至少选择一个要筛选的对象

演示:

我手头没有任何东西可以验证这一点并作为答案发布,但是
FormGroup
FormControl
(可能还有
FormArray
)继承自
AbstractControl
,它有一个
toucted()
方法。您应该能够在
FormGroup
上调用此方法,并查明是否已触摸它或任何子
FormControls
。。。您还可以使用
FormControl
value
属性,在需要知道表单控件名称的情况下对值进行迭代…结果如何,是否符合您的要求?:)如果在未选择值的情况下打开和关闭选择输入,是否认为触摸了该输入??我认为只要用户随后离开该字段就可以了。但您可能需要运行一个小测试来确认。奇怪的是,扩展然后关闭下拉列表不会触发此操作。如果我选择一个值,然后删除该值,它就可以正常工作。即使您随后离开该字段?有趣。不是我想的那样。单击下拉图标似乎不被视为“进入”该字段?