在反应形式表单组中设置动态 ValidationFn
Set dynamic ValidationFn in reactive form formgroup
我正在尝试创建一个非常 generic\dynamic 的反应式表单,它可以对表单组使用自定义验证函数(以比较 2 个日期)。该函数实际上可以是任何类型为 ValidatorFn:
的验证函数
export interface ValidatorFn {
(control: AbstractControl): ValidationErrors | null;
}
这是根本问题:
我在一种配置文件中定义函数,并用它初始化反应形式(接收函数作为参数)并使用 validationFn 设置 formGroup。
这是函数:
customValidationFunction : ValidatorFn = (group : FormGroup) : ValidationErrors | null =>
{
return (/*control : AbstractControl*/)/*:{[key: string] : any} | null*/ =>
{
if (group.controls["CreatedDateFormatFrom"] && group.controls["CreatedDateFormatTo"])
{
let from : AbstractControl = group.get("CreatedDateFormatFrom");
let to : AbstractControl = group.get("CreatedDateFormatTo");
const inValid = from && to && to.value < from.value;
return inValid ? {'invalidDates' : true } : null;
}
return null;
}
}
现在,在 "customize\generic\dynamically created" 响应式表单初始化中,我设置了函数(或一些函数):
initForm(formGroupCustomValidation? : ValidatorFn[] )
{
let group: any = {};
//Here I initiate the group with FormControls, for example:
group[<fieldName>] = new FormControl(<some value> || '');
//This is where the custom validation function comes:
if (formGroupCustomValidation)
{
this.form = new FormGroup(group, {validators:
formGroupCustomValidation });
}
this.form.valueChanges.subscribe(values => {
console.log(values);
this.formValid();
})
}
我很抱歉 "blurry" 代码,但这是由于动态创建的表单。
问题是如何传递和执行带有 group:FormGroup 参数的函数?
我倾向于认为我对函数 definition\scope 等有一些问题。
尝试调试函数时,我看不到触发的函数体。
请支持。
您不必 return 另一个函数,因为您没有传递额外的参数,这就足够了:
customValidationFunction: ValidatorFn = (group: FormGroup) => {
const from: AbstractControl = group.get('CreatedDateFormatFrom');
const to: AbstractControl = group.get('CreatedDateFormatTo');
if (from && to) {
const inValid = from && to && to.value < from.value;
return inValid ? {'invalidDates': true} : null;
}
return null;
}
编辑 1:
好的,我漏掉了一点,因为您想将第一组传递给第二组并对第一组的控件执行验证。
应该可行:
const group = new FormGroup({
CreatedDateFormatFrom: new FormControl(),
CreatedDateFormatTo: new FormControl()
});
const group2 = new FormGroup({anotherGroup: group}, this.customValidationFunction(group));
group.controls.CreatedDateFormatFrom.setValue('11-12-2018');
group.controls.CreatedDateFormatTo.setValue('11-11-2018');
customValidationFunction: ValidatorFn = (group: FormGroup) => {
return () => {
const from: AbstractControl = group.get('CreatedDateFormatFrom');
const to: AbstractControl = group.get('CreatedDateFormatTo');
if (from && to) {
const inValid = from && to && to.value < from.value;
return inValid ? {'invalidDates': true} : null;
}
return null;
};
}
好的,我找到了@Buczkowski 提到的解决方案。这是我更正的代码(故意注释掉的左侧代码 - 以显示差异):
customValidationFunction: ValidatorFn /*: ValidatorFn*/ = (group : FormGroup) /*:
ValidationErrors | null*/ =>
{
/*return (control : AbstractControl):{[key: string] : any} | null =>
{*/
if (group.controls["CreatedDateFormatFrom"] &&
group.controls["CreatedDateFormatTo"])
{
let from : AbstractControl = group.get("CreatedDateFormatFrom");
let to : AbstractControl = group.get("CreatedDateFormatTo");
const inValid : boolean = from && to && from.value && to.value && to.value < from.value;
return inValid ? {'invalidDates' : true } : null;
}
return null;
/*}*/
}
我正在尝试创建一个非常 generic\dynamic 的反应式表单,它可以对表单组使用自定义验证函数(以比较 2 个日期)。该函数实际上可以是任何类型为 ValidatorFn:
的验证函数export interface ValidatorFn {
(control: AbstractControl): ValidationErrors | null;
}
这是根本问题:
我在一种配置文件中定义函数,并用它初始化反应形式(接收函数作为参数)并使用 validationFn 设置 formGroup。
这是函数:
customValidationFunction : ValidatorFn = (group : FormGroup) : ValidationErrors | null =>
{
return (/*control : AbstractControl*/)/*:{[key: string] : any} | null*/ =>
{
if (group.controls["CreatedDateFormatFrom"] && group.controls["CreatedDateFormatTo"])
{
let from : AbstractControl = group.get("CreatedDateFormatFrom");
let to : AbstractControl = group.get("CreatedDateFormatTo");
const inValid = from && to && to.value < from.value;
return inValid ? {'invalidDates' : true } : null;
}
return null;
}
}
现在,在 "customize\generic\dynamically created" 响应式表单初始化中,我设置了函数(或一些函数):
initForm(formGroupCustomValidation? : ValidatorFn[] )
{
let group: any = {};
//Here I initiate the group with FormControls, for example:
group[<fieldName>] = new FormControl(<some value> || '');
//This is where the custom validation function comes:
if (formGroupCustomValidation)
{
this.form = new FormGroup(group, {validators:
formGroupCustomValidation });
}
this.form.valueChanges.subscribe(values => {
console.log(values);
this.formValid();
})
}
我很抱歉 "blurry" 代码,但这是由于动态创建的表单。 问题是如何传递和执行带有 group:FormGroup 参数的函数? 我倾向于认为我对函数 definition\scope 等有一些问题。 尝试调试函数时,我看不到触发的函数体。 请支持。
您不必 return 另一个函数,因为您没有传递额外的参数,这就足够了:
customValidationFunction: ValidatorFn = (group: FormGroup) => {
const from: AbstractControl = group.get('CreatedDateFormatFrom');
const to: AbstractControl = group.get('CreatedDateFormatTo');
if (from && to) {
const inValid = from && to && to.value < from.value;
return inValid ? {'invalidDates': true} : null;
}
return null;
}
编辑 1:
好的,我漏掉了一点,因为您想将第一组传递给第二组并对第一组的控件执行验证。
应该可行:
const group = new FormGroup({
CreatedDateFormatFrom: new FormControl(),
CreatedDateFormatTo: new FormControl()
});
const group2 = new FormGroup({anotherGroup: group}, this.customValidationFunction(group));
group.controls.CreatedDateFormatFrom.setValue('11-12-2018');
group.controls.CreatedDateFormatTo.setValue('11-11-2018');
customValidationFunction: ValidatorFn = (group: FormGroup) => {
return () => {
const from: AbstractControl = group.get('CreatedDateFormatFrom');
const to: AbstractControl = group.get('CreatedDateFormatTo');
if (from && to) {
const inValid = from && to && to.value < from.value;
return inValid ? {'invalidDates': true} : null;
}
return null;
};
}
好的,我找到了@Buczkowski 提到的解决方案。这是我更正的代码(故意注释掉的左侧代码 - 以显示差异):
customValidationFunction: ValidatorFn /*: ValidatorFn*/ = (group : FormGroup) /*:
ValidationErrors | null*/ =>
{
/*return (control : AbstractControl):{[key: string] : any} | null =>
{*/
if (group.controls["CreatedDateFormatFrom"] &&
group.controls["CreatedDateFormatTo"])
{
let from : AbstractControl = group.get("CreatedDateFormatFrom");
let to : AbstractControl = group.get("CreatedDateFormatTo");
const inValid : boolean = from && to && from.value && to.value && to.value < from.value;
return inValid ? {'invalidDates' : true } : null;
}
return null;
/*}*/
}