获取在FormGroup/FormControl中存在的验证器 [英] Get validators present in FormGroup/FormControl

查看:303
本文介绍了获取在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上显示键入ValidatorFnvalidator成员.不幸的是,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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆