有没有办法查找Angular2 FormControl中是否为控件注册了必需的验证器。
this.form = builder.group({name: ['', Validators.required]};
如果我想查询this.form.controls['name']
控件是否为必填字段,那么该怎么办呢?我知道我可以检查它是否有效,但这不是我想要的。
此致敬礼, 马克
有没有办法查找Angular2 FormControl中是否为控件注册了必需的验证器。
this.form = builder.group({name: ['', Validators.required]};
如果我想查询this.form.controls['name']
控件是否为必填字段,那么该怎么办呢?我知道我可以检查它是否有效,但这不是我想要的。
此致敬礼, 马克
这个函数应该适用于FormGroup和FormControl。
export const hasRequiredField = (abstractControl: AbstractControl): boolean => {
if (abstractControl.validator) {
const validator = abstractControl.validator({}as AbstractControl);
if (validator && validator.required) {
return true;
}
}
if (abstractControl['controls']) {
for (const controlName in abstractControl['controls']) {
if (abstractControl['controls'][controlName]) {
if (hasRequiredField(abstractControl['controls'][controlName])) {
return true;
}
}
}
}
return false;
};
false
而不是 null
? - Andre ElricohasValidator
,您可以使用它来检查一个formcontrol是否具有同步验证器。如果您需要检查它是否具有异步验证器,也可以使用hasAsyncValidator
。this.form.get('name').hasValidator(Validators.required);
(this.form.get('name') as FormControl).hasValidator(Validators.required);
hasValidator()
是在12版中引入的,因此在此之后的任何版本中,这个答案都应该是有效的。 - AT82虽然没有 Angular API 直接查找特定字段是否设置了 required
验证器,但可通过以下方式间接实现:
import { NgForm, FormControl } from '@angular/forms';
const isRequiredControl = (formGroup: NgForm, controlName: string): boolean => {
const { controls } = formGroup
const control = controls[controlName]
const { validator } = control
if (validator) {
const validation = validator(new FormControl())
return validation !== null && validation.required === true
}
return false
}
我已经进行过测试,只有在特定的FormControl
中添加了Validator.Required
验证器时,它才会触发。
目前没有方法可以检查验证器或获取所有验证器:https://github.com/angular/angular/issues/13461
@fairlie-agile的解决方案非常聪明。但我认为我们必须使用空的FormControl,因为我们需要触发必填验证器,this.group.controls[this.config.name]
可能已经用某个值初始化。
ngOnInit() {
let formControl = this.group.controls[this.config.name];
let errors: any = formControl.validator && formControl.validator(new FormControl());
this._required = errors !== null && errors.required;
}
一种方法是在表单加载时检查控件是否有效,以查看它是否具有所需的错误(如果字段为空,则会出现此错误)。
这对于其他验证器(例如minLength)不起作用,因为它们直到更改控件才会触发。
export class FormInputComponent implements Field, OnInit {
private _required: boolean;
config: FieldConfig;
group: FormGroup;
/** Readonly properties. */
get required(): boolean {
return this._required;
}
ngOnInit() {
var _validator: any = this.group.controls[this.config.name].validator && this.group.controls[this.config.name].validator(this.group.controls[this.config.name]);
this._required = _validator && _validator.required;
}
}
我有类似的问题。目前,我正在使用这个:
import { Attribute } from '@angular/core';
// "Kind-of" hack to allow "pass-through" of the required attribute
constructor(@Attribute('required') public required) {
// call super here if the component is an ancestor
}
我很困惑为什么FormControl中包含了像“disabled”这样的属性,但没有“required”。
get lastPriceField(): AbstractControl {
return this.form.get('last_price');
}
private checkIfFieldHasValidatorRequired() {
const validators = (this.lastPriceField as any)._rawValidators;
this._lastPriceIsRequired = validators && validators.some(item => item.name === "required");
}
假设最初仅注册的错误是required
错误
// in your component you'll have access to `this.myFormGroup`
const formGroup = {
controls: {
email: {
errors: {
required: true
}
},
username: {
errors: null
}
}
}
// required by default
let required = {
email: '*',
username: '*',
};
// in `ngOnInit`
required = Object.entries(formGroup.controls)
.map(([key, control]) => [key, control.errors])
.filter(([, errors]) => !errors)
.map(([key]) => [key, ''])
.reduce((_required, [key, isRequired]) => Object.assign(_required, { [key]: isRequired }), required)
// in your template you may write `<label>Email{{ required.email }}</label>`
console.log(required)
private readonly emptyFormControl = new FormControl();
然后在方法中进行检查。如果控件已启用并且其验证器在验证空控件时出现“必填”错误,则必须使用控件。
private isMandatory = (fc: FormControl): boolean =>
fc.enabled && !!fc.validator && !!fc.validator(this.emptyFormControl)?.required;
这仅适用于FormControl对象。如果您需要支持FormGroup或/和FormArray,则需要将递归添加到检查方法中。
我不知道检查控件是否有必填验证器的确切方法是什么。
但是可以采用以下解决方法,每当控件具有必填验证器时,它会向该控件添加validator()函数。
例如:
<input type="text" formControlName="firstname">
constructor(private formBuilder: FormBuilder){
this.registerForm = this.formBuilder.group({
firstname: ['', Validators.required] //<<<===one required validation on firstname control
});
console.log(this.registerForm.controls.firstname.validator.length);
//<<<===this will return 1.
});
}
在上面的代码中,验证器的长度为1。 console.log(this.registerForm.controls.firstname.validator.length);
//this will return exception
这行代码将返回1。如果没有附加验证器,那么firstname将不会有validator()函数,因此在这种情况下,我会抛出异常。