dev*_*054 17 typescript angular2-forms angular-material2 angular
我在我的应用程序中使用了Material 2,但在这个问题中,我想用Input专门解决问题.
正如您在API Reference中看到的那样,有一个名为的属性绑定required
,在占位符中显示为星号.
所以,我想知道是否有办法检查表单控件是否在Angular中有一个特定的验证器,因为我真的不想为每个输入手动设置[required]="true/false"
我阅读了AbstractControl文档,但我没有找到任何相关内容.我遇到的hasError
方法(这具有讽刺意味的是没有记录无处 ......无论是在FormGroup也不FormControl也不AbstractControl),但是这不是我要找的.它只是检查表单控件是否有错误,但正如您可能已阅读过,我想检查控件是否有一些特定的验证器...
一些代码:
<md-input-container>
<input placeholder="Placeholder"
mdInput [formControl]="anyCtrl"
[required]="anyCtrl.hasValidator('required')"> <!-- something like this -->
</md-input-container>
Run Code Online (Sandbox Code Playgroud)
我希望这个问题足够清楚.提前致谢.
joh*_*667 24
Angular并没有真正提供一个很好的,干净的方法,但它是可能的.我认为验证器存储在注入FormBuilder(NG_VALIDATORS
)的服务中,我将研究劫持该服务或将其注入组件,但是现在这将起作用:
该文档和源显示validator
的成员AbstractControl
类型来ValidatorFn
.ValidatorFn
不幸的是只是null
打字,所以我们无法看到发生了什么.但是,在浏览生成的源并探测应用程序之后,似乎我们可以向此validators
方法传递一个control
参数,该参数将返回该控件上存在的所有验证器的对象,而不管它是否正在通过.
奇怪的是,这只适用于FormControl
自身,而不是FormGroup
(在成员上FormGroup
,validators
成员不是一个功能,而且总是null
在我的测试中).编译好的JS说这个函数需要一个control
参数; 我已经尝试传入FormControl
引用,但据我所知它只会返回控件上的验证器,只要此参数不为null.
// 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}
Run Code Online (Sandbox Code Playgroud)
public hasValidator(control: string, validator: string): boolean {
return !!this.myForm.controls[control].validators(control).hasOwnProperty(validator);
// returns true if control has the validator
}
Run Code Online (Sandbox Code Playgroud)
在你的标记中:
<md-input-container>
<input placeholder="Placeholder"
mdInput [formControl]="anyCtrl"
[required]="hasValidator('anyCtrl', 'email')">
</md-input-container>
Run Code Online (Sandbox Code Playgroud)
该required
验证器的快捷方式.的[required]
结合实际上是实例RequiredValidator
指令(源极/ forms.js的线5022).该指令实际上会将required
Validator 添加到其中FormControl
.这相当于增加了Validators.required
在FormGroup
初始化时.因此,将bound属性设置为false required
将从该控件中删除Validator,反之亦然......无论哪种方式,该指令都会影响该FormControl.required
值,因此将其绑定到它更改的属性并不会真正起作用.
唯一的区别是该[required]
指令将星号添加到占位符而Validators.required
不是.
我将继续关注NG_VALIDATORS
,但我希望现在有所帮助!
pas*_*sek 21
Angular v12.2 推出hasValidator()
:https://github.com/angular/angular/pull/42838
例子:this.formGroup.controls['anyCtrl'].hasValidator(Validators.required)
您还可以稍后以编程方式添加或删除验证器。参见addValidators()
、removeValidators()
、 和其他。
https://angular.io/api/forms/AbstractControl#hasValidator
如果你想检查一个控制器是否有特定的验证器,对于 Angular 12.2+ 来说非常简单
例如,
let controller = new FormControl('', [Validators.required])
console.log(controller.hasValidator(Validators.required))//true
Run Code Online (Sandbox Code Playgroud)
但是,这不适用于Validators.minLength()
、Validators.maxLength()
、Validators.min()
或Validators.max
任何需要参数的验证器。
为了使其工作,您需要为该验证器创建一个引用,并将该引用添加到表单控制器验证器和函数中hasValidator
。
例如,
const minLengthValidator = Validators.minLength(60);
let controller = new FormControl('', [minLengthValidator])
console.log(controller.hasValidator(minLengthValidator)) //true
Run Code Online (Sandbox Code Playgroud)
但如果你执行以下操作,你会得到错误的结果:
let controller = new FormControl('', [ Validators.minLength(60)])
console.log(controller.hasValidator( Validators.minLength(60))) //false
Run Code Online (Sandbox Code Playgroud)
这个答案是@joh04667's的延续。他们写:
public hasValidator(control: string, validator: string): boolean {
return !!this.myForm.controls[control].validators(control).hasOwnProperty(validator);
// returns true if control has the validator
}
Run Code Online (Sandbox Code Playgroud)
然而没有AbstractControls.validators()
方法。我假设AbstractControls.validator()
是这个意思。
该hasValidator()
方法仅适用于“失败”的验证器(例如,控件上具有值“(空)”的必需验证器)。因为如果他们通过他们返回null。解决此问题的一种方法是设置该值,使其始终失败并在之后恢复该值。
public hasValidator(control: string, validator: string): boolean {
let control: AbstractControl = this.myForm.controls[control];
let lastValue: any = control.value;
switch(validator) {
case 'required':
control.setValue(''); // as is appropriate for the control
case 'pattern':
control.setValue('3'); // given you have knowledge of what the pattern is - say its '\d\d\d'
....
}
let hasValidator: boolean = !!control.validator(control).hasOwnProperty(validator);
control.setValue(lastValue);
return hasValidator;
}
Run Code Online (Sandbox Code Playgroud)
这是非常可怕的。这就引出了一个问题——为什么没有AbstractControl.getValidators(): ValidatorFn[]|null
?
隐藏这个的动机是什么?也许他们担心有人可能会放入他们的代码:
...
secretPassword: ['', [Validators.pattern('fjdfjafj734738&UERUEIOJDFDJj')]
...
Run Code Online (Sandbox Code Playgroud)
没有直接或干净的方法可以做到这一点。这是我遇到的最干净、有效的方法。使用最新版本的Angular v10.2.0进行测试(截至今天)
导入这些
import {AbstractControl, FormControl, Validators} from '@angular/forms';
Run Code Online (Sandbox Code Playgroud)
定义您的控制
anyCtrl = new FormControl('', [Validators.required]);
Run Code Online (Sandbox Code Playgroud)
添加这个方法
public hasRequiredField = (abstractControl: AbstractControl): boolean => {
if (abstractControl.validator) {
const validator = abstractControl.validator({}as AbstractControl);
if (validator && validator.required) {
return true;
}
}
return false;
}
Run Code Online (Sandbox Code Playgroud)
如何从 HTML 调用此方法
<input placeholder="Placeholder" [formControl]="anyCtrl" [required]="hasRequiredField(anyCtrl)">
Run Code Online (Sandbox Code Playgroud)
在构造函数或 ngOnInit 中从 Typescript 文件(逻辑)调用它
constructor() {
console.log(this.hasRequiredField(this.anyCtrl)); // true, false if Validators array does not contain Validators.required
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
11376 次 |
最近记录: |