获取在FormGroup/FormControl中存在的验证器 [英] Get validators present in FormGroup/FormControl
问题描述
我在我的应用程序中使用了Material 2,但是在这个问题中,我想专门解决
我阅读了 AbstractControl 文档,但我什么都没找到.我遇到了hasError
方法(具有讽刺意味的是,无处不在中没有对此文档进行记录……在FormGroup,FormControl中或在AbstractControl),但这不是我想要的.它只是检查表单控件是否有错误,但是,正如您可能已经读过的那样,我想检查该控件是否具有一些特定的验证器...
某些代码:
<md-input-container>
<input placeholder="Placeholder"
mdInput [formControl]="anyCtrl"
[required]="anyCtrl.hasValidator('required')"> <!-- something like this -->
</md-input-container>
我希望这个问题足够清楚.预先感谢.
Angular确实没有提供一种很好的,干净的方法来做到这一点,但是有可能.我认为验证器存储在注入FormBuilder(NG_VALIDATORS
)的服务中,我将研究劫持该服务或将其注入组件,但现在可以使用:
文档,并且源在AbstractControl
上显示键入ValidatorFn
的validator
成员.不幸的是,ValidatorFn
只是简单地输入了null
,所以我们看不到发生了什么.但是,在浏览生成的源并探查应用程序之后,似乎我们可以将此validators
方法传递给control
参数,该参数将返回该控件上存在的所有验证器的对象,而不管其是否通过.
奇怪的是,这个 only 仅对FormControl
本身起作用,而不对FormGroup
起作用(在FormGroup
上,validators
成员不是函数,并且在null
中始终是null
我的测试).编译后的JS表示此函数采用control
参数.我尝试传递FormControl
引用,但据我所知,只要此参数不为null,它将仅返回控件上的验证器.
在FormControl上获取验证器
// in the constructor
this.myForm = this.formBuilder.group({
'anyCtrl': ['', Validators.required],
'anotherCtrl': ['', Validators.compose([Validators.required, Validators.email])]
});
// later on
let theValidators = this.myForm.controls['anyCtrl'].validator('');
console.log(theValidators) // -> {required: true};
let otherValidators = this.myForm.controls['anotherCtrl'].validator('');
console.log(otherValidators); // -> {required: true, email: true}
使抓取更容易:
public hasValidator(control: string, validator: string): boolean {
return !!this.myForm.controls[control].validators(control).hasOwnProperty(validator);
// returns true if control has the validator
}
并在您的标记中:
<md-input-container>
<input placeholder="Placeholder"
mdInput [formControl]="anyCtrl"
[required]="hasValidator('anyCtrl', 'email')">
</md-input-container>
验证者的特殊情况.
required
验证器具有快捷方式. [required]
绑定实际上是RequiredValidator
指令的实例(source/forms.js的5022行).该指令实际上会将required
验证器添加到启用的FormControl
中.等效于在初始化时将Validators.required
添加到FormGroup
.因此,将bound属性设置为false会从该控件中删除required
验证程序,反之亦然……无论哪种方式,该指令都会影响FormControl.required
值,因此将其绑定到它更改的属性上并不会真正起作用很多.
唯一的区别是[required]
指令将星号添加到占位符,而Validators.required
则没有.
我将继续研究NG_VALIDATORS
,但我希望现在有帮助!
I'm using Material 2 in my app, but in this question I want to solve a problem specifically with Input.
As you can see in API Reference there's a property bind called required
, which shows as asterisk in the placeholder.
So, I'm wondering if there's a way to check if the form control has an specific validator in Angular, because I really don't want to set manually for each input [required]="true/false"
I read the AbstractControl docs and I didn't find anything about it. I've encountered the hasError
method (which ironically isn't documented in nowhere ... neither in FormGroup nor in FormControl nor in AbstractControl), however this is not what I'm looking for. It just checks if the form control has the error, but as you may have read, I want to check if the control has some specific validators...
Some code:
<md-input-container>
<input placeholder="Placeholder"
mdInput [formControl]="anyCtrl"
[required]="anyCtrl.hasValidator('required')"> <!-- something like this -->
</md-input-container>
I hope the question is clear enough. Thanks in advance.
Angular doesn't really provide a great, clean way to do this, but it is possible. I think the validators are stored in a service that is injected into the FormBuilder(NG_VALIDATORS
), and I'm going to look into hijacking that service or injecting it into a component, but for now this will work:
The docs and the source show a validator
member on AbstractControl
typed to ValidatorFn
. ValidatorFn
unfortunately simply has a null
typing, so we can't see what's going on. However, after poking through the generated source and probing an app, it seems we can pass this validators
method a control
parameter, which will return an object of all validators present on that control, regardless of whether or not it's passing.
Strangely, this only works on the FormControl
itself and not the FormGroup
(on the FormGroup
, the validators
member is not a function and was always null
in my testing). The compiled JS says this function takes a control
parameter; I've tried passing in FormControl
references but as far as I can tell it will just return the validators on the control as long as this parameter is not null.
Getting validators on a FormControl
// in the constructor
this.myForm = this.formBuilder.group({
'anyCtrl': ['', Validators.required],
'anotherCtrl': ['', Validators.compose([Validators.required, Validators.email])]
});
// later on
let theValidators = this.myForm.controls['anyCtrl'].validator('');
console.log(theValidators) // -> {required: true};
let otherValidators = this.myForm.controls['anotherCtrl'].validator('');
console.log(otherValidators); // -> {required: true, email: true}
Making it easier to grab:
public hasValidator(control: string, validator: string): boolean {
return !!this.myForm.controls[control].validators(control).hasOwnProperty(validator);
// returns true if control has the validator
}
and in your markup:
<md-input-container>
<input placeholder="Placeholder"
mdInput [formControl]="anyCtrl"
[required]="hasValidator('anyCtrl', 'email')">
</md-input-container>
Special case for Validators.required
The required
validator has a shortcut. The [required]
binding is actually an instance of the RequiredValidator
directive (line 5022 of source/forms.js). This directive actually will add the required
Validator to the FormControl
it's on. It's equivalent to adding Validators.required
to the FormGroup
upon initialization. So, setting the bound property to false will remove the required
Validator from that control and vice versa...either way, the directive effects the FormControl.required
value, so binding it to a property that it changes won't really do much.
The only difference is that the [required]
directive adds the asterisk to the placeholder while Validators.required
does not.
I'm going to keep looking into NG_VALIDATORS
, but I hope this helps for now!
这篇关于获取在FormGroup/FormControl中存在的验证器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!