2017-07-25 69 views
0

我有一个为我的组件生成的反应窗体。大约有5个可选的选择输入,用户可以选择使用并从中选择标准。Angular2 - 活性窗体属性

我想在此实现一些错误消息,但不能完全弄清楚什么。

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

由于所有字段是选项,但至少有一个是必须的,我怎么可能去检查该字段中的一个已显示无效消息touched之前?

组件:

/** 
* 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,如果我能帮助它。

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

+0

我没有什么得心应手,以验证这一点,后一个答案,但'FormGroup'和'FormControl '(可能是'FormArray')从'AbstractControl'继承,''touch()'方法。你应该可以在FormGroup上调用这个方法,看看它是否已经触及子FormControls ...你也可以使用FormControl的value属性遍历值必须知道表单控件名称... –

+0

它是如何与答案一起去的,是否符合您的要求? :) – Alex

回答

1

在这里,我想删除自定义验证因为它位于现在。只要你的表单发生了什么,它就会被触发,我认为它的值比选择更多。这会经常引起不必要的火灾

相反,我会听click事件或类似的选择。下面的例子可能会更精确一些(?),但至少你有一些工作,如果你选择以下面的方式做。

这里我假设的,而不是形式使用所有select一个数组,你只是想捕捉一个值,其中单FormControl会做:

this.importForm = this.fb.group({ 
    optionals: this.fb.group({ 
    costCenter: [''], 
    area: ['']   
    }) 
}); 

的构建之后窗体,我喜欢将不同的控件存储到变量中,以避免使用属性路径的冗长代码。我会遍历在formgroup optionals对象属性,将其存储在阵列,然后我们可以检查并确保至少一个值设置:

this.optionalCtrl = this.importForm.controls.optionals 

模板,那么,在这里,你将需要设置的点击事件为所有选择单独...然后

<select formControlName="costCenter" (click)="checkOptionals()"> 

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

checkOptionals() { 
    for(let key in this.optionalCtrl.controls) { 
    if(this.optionalCtrl.controls[key].value != '') { 
     this.optionalCtrl.clearValidators() 
     // this.optionalCtrl.updateValueAndValidity() 
     break; 
    } else { 
     this.optionalCtrl.setErrors({"noFilterOptions": true}) 
    } 
    } 

}}

您可能需要设置错误之后调用updateValueAndValidity。然后在模板中,您只是显示这个错误时,它的truthy:

<div *ngIf="optionalCtrl.hasError('noFilterOptions')"> 
    choose at least one to filter by 
</div> 

DEMO:http://plnkr.co/edit/VbtsYST0KAUqe8BRQlmt?p=preview

0

你在这里什么应该工作:

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

如果任何窗体上的控件都被感动的感动属性的形式进行设置。我认为它不工作?它怎么不起作用?

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

如果你想知道,如果用户更新输入要素之一的值,用肮脏来代替:

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

如果一个选择输入打开和关闭而没有选择一个值会怎么样,是否被认为是“被触摸”? – SBB

+0

我会认为只要用户*离开该领域之后。但是你可能想要运行一个小测试来确认。 – DeborahK

+0

奇怪的是,扩大,然后关闭下拉不会触发这一点。如果我选择一个值,然后删除该值,它工作得很好。 – SBB