如何根据其他 Formfields 更改 Formfields 上的验证?
How to change validation on a Formfield depending on other Formfields?
目标是实现一个表单,仅当填写了一个或多个输入字段时才需要输入字段。如果 none 个字段已填写,则不需要任何字段。有人在网站上建议我应该使用“valueChanges”在字段上创建一个监听器,然后在监听器中实现逻辑。然后在侦听器内部的逻辑之后,我调用方法“updateValueAndValidity()”。
现在这里出现问题。如果我包含“updateValueAndValidity()”,我会收到错误消息:
Recursion Error in the Browser。我真的不明白为什么我在这个问题上会出现递归错误,因为我看不到递归在哪里。可能“updateValueAndValidity()”再次触发了我的监听器。
如果我不包含“updateValueAndValidity()”,我不会收到递归错误,但逻辑不起作用。我不知道如何解决这个问题,有人可以帮助我吗?
isFormEmtpy: boolean = true;
lieferadresseForm: FormGroup;
onChanges() {
let street = this.lieferadresseForm.get('street');
let streetNumber = this.lieferadresseForm.get('streetNumber');
let zipCode = this.lieferadresseForm.get('zipCode');
this.lieferadresseForm.valueChanges.subscribe(val => {
console.log(val);
this.isFormEmtpy = true;
if(val.street !== '') {
this.isFormEmtpy = false;
} else if(val.streetNumber !== '') {
this.isFormEmtpy = false;
} else if(val.zipCode !== '') {
this.isFormEmtpy = false;
}
if(this.isFormEmtpy == false) {
street.setValidators([Validators.required, Validators.maxLength(36)]);
streetNumber.setValidators([Validators.required, Validators.maxLength(10)]);
zipCode.setValidators([Validators.required, Validators.maxLength(10)]);
} else {
street.setValidators([Validators.maxLength(36)]);
streetNumber.setValidators([Validators.maxLength(10)]);
zipCode.setValidators([Validators.maxLength(10)]);
}
strasse.updateValueAndValidity();
hausnummer.updateValueAndValidity();
postleitzahl.updateValueAndValidity();
});
}
ngOnInit() {
this.lieferadresseForm = this.formBuilder.group({
street: ['', Validators.maxLength(36)],
streetNumber: ['', Validators.maxLength(10)],
zipCode: ['', Validators.maxLength(10)]
});
this.onChanges();
}
您需要在 formControl 上使用 updateValueAndValidity()
。
yourForm.controls['controlName'].updateValueAndValidity();
在你的情况下会像
lieferadresseForm.controls['streetNumber']..updateValueAndValidity();
您可以将 {emitEvent:false} 对象配置传递给 updateValueAndValidity 方法以停止触发 valueChanges observable。
试试这个:
onChanges() {
let street = this.lieferadresseForm.get('street');
let streetNumber = this.lieferadresseForm.get('streetNumber');
let zipCode = this.lieferadresseForm.get('zipCode');
this.lieferadresseForm.valueChanges.subscribe(val => {
console.log(val);
this.isFormEmtpy = true;
if(val.street !== '') {
this.isFormEmtpy = false;
} else if(val.streetNumber !== '') {
this.isFormEmtpy = false;
} else if(val.zipCode !== '') {
this.isFormEmtpy = false;
}
if(this.isFormEmtpy == false) {
street.setValidators([Validators.required, Validators.maxLength(36)]);
streetNumber.setValidators([Validators.required, Validators.maxLength(10)]);
zipCode.setValidators([Validators.required, Validators.maxLength(10)]);
} else {
street.setValidators([Validators.maxLength(36)]);
streetNumber.setValidators([Validators.maxLength(10)]);
zipCode.setValidators([Validators.maxLength(10)]);
}
strasse.updateValueAndValidity({emitEvent:false});
hausnummer.updateValueAndValidity({emitEvent:false});
postleitzahl.updateValueAndValidity({emitEvent:false});
});
}
问题是您正在订阅表单值更改到 onChange function.Basically您正在订阅表单更改在每个更改检测周期创建新的订阅,这会导致巨大的内存泄漏。
将您编写的代码移到 ngOnInit 函数或至少一个只调用一次的函数中。
在这种情况下,您不需要处理 onChange 生命周期,因为您正在监听表单更改本身。
最好创建一个自定义的formGroup的formError。它比你想象的更简单:只需在你的组件中创建一个函数:
requiredIfOneNotEmpty()
{
return (formGroup:FormGroup)=>{
const oneFilled=formGroup.value.street ||
formGroup.value.streetNumber ||
formGroup.value.zipCode
if (!oneFilled)
return null
const error={}
if (!formGroup.value.street)
error.requiredStreet='Street is required';
if (!formGroup.value.streetNumber )
error.requiredStreetNumber='Street number is required'
if (!formGroup.value.zipCode)
error.requiredZipCode:'Zip code is required'
return error
}
}
然后您可以简单地创建表单
formGroup=new FormGroup({
street:new FormControl(null,Validators.maxLength(36)),
streetNumber:new FormControl(null,Validators.maxLength(10)),
zipCode:new FormControl(null,Validators.maxLength(10));
},this.requiredIfOneNotEmpty())
你检查错误使用
<div *ngIf="formGroup.errors?.requiredStreet">Required Street</div>
<div *ngIf="formGroup.errors?.requiredStreetNumber">Required Street Number</div>
<div *ngIf="formGroup.errors?.requiredZipCode">Required Zip Code</div>
目标是实现一个表单,仅当填写了一个或多个输入字段时才需要输入字段。如果 none 个字段已填写,则不需要任何字段。有人在网站上建议我应该使用“valueChanges”在字段上创建一个监听器,然后在监听器中实现逻辑。然后在侦听器内部的逻辑之后,我调用方法“updateValueAndValidity()”。 现在这里出现问题。如果我包含“updateValueAndValidity()”,我会收到错误消息: Recursion Error in the Browser。我真的不明白为什么我在这个问题上会出现递归错误,因为我看不到递归在哪里。可能“updateValueAndValidity()”再次触发了我的监听器。
如果我不包含“updateValueAndValidity()”,我不会收到递归错误,但逻辑不起作用。我不知道如何解决这个问题,有人可以帮助我吗?
isFormEmtpy: boolean = true;
lieferadresseForm: FormGroup;
onChanges() {
let street = this.lieferadresseForm.get('street');
let streetNumber = this.lieferadresseForm.get('streetNumber');
let zipCode = this.lieferadresseForm.get('zipCode');
this.lieferadresseForm.valueChanges.subscribe(val => {
console.log(val);
this.isFormEmtpy = true;
if(val.street !== '') {
this.isFormEmtpy = false;
} else if(val.streetNumber !== '') {
this.isFormEmtpy = false;
} else if(val.zipCode !== '') {
this.isFormEmtpy = false;
}
if(this.isFormEmtpy == false) {
street.setValidators([Validators.required, Validators.maxLength(36)]);
streetNumber.setValidators([Validators.required, Validators.maxLength(10)]);
zipCode.setValidators([Validators.required, Validators.maxLength(10)]);
} else {
street.setValidators([Validators.maxLength(36)]);
streetNumber.setValidators([Validators.maxLength(10)]);
zipCode.setValidators([Validators.maxLength(10)]);
}
strasse.updateValueAndValidity();
hausnummer.updateValueAndValidity();
postleitzahl.updateValueAndValidity();
});
}
ngOnInit() {
this.lieferadresseForm = this.formBuilder.group({
street: ['', Validators.maxLength(36)],
streetNumber: ['', Validators.maxLength(10)],
zipCode: ['', Validators.maxLength(10)]
});
this.onChanges();
}
您需要在 formControl 上使用 updateValueAndValidity()
。
yourForm.controls['controlName'].updateValueAndValidity();
在你的情况下会像
lieferadresseForm.controls['streetNumber']..updateValueAndValidity();
您可以将 {emitEvent:false} 对象配置传递给 updateValueAndValidity 方法以停止触发 valueChanges observable。
试试这个:
onChanges() {
let street = this.lieferadresseForm.get('street');
let streetNumber = this.lieferadresseForm.get('streetNumber');
let zipCode = this.lieferadresseForm.get('zipCode');
this.lieferadresseForm.valueChanges.subscribe(val => {
console.log(val);
this.isFormEmtpy = true;
if(val.street !== '') {
this.isFormEmtpy = false;
} else if(val.streetNumber !== '') {
this.isFormEmtpy = false;
} else if(val.zipCode !== '') {
this.isFormEmtpy = false;
}
if(this.isFormEmtpy == false) {
street.setValidators([Validators.required, Validators.maxLength(36)]);
streetNumber.setValidators([Validators.required, Validators.maxLength(10)]);
zipCode.setValidators([Validators.required, Validators.maxLength(10)]);
} else {
street.setValidators([Validators.maxLength(36)]);
streetNumber.setValidators([Validators.maxLength(10)]);
zipCode.setValidators([Validators.maxLength(10)]);
}
strasse.updateValueAndValidity({emitEvent:false});
hausnummer.updateValueAndValidity({emitEvent:false});
postleitzahl.updateValueAndValidity({emitEvent:false});
});
}
问题是您正在订阅表单值更改到 onChange function.Basically您正在订阅表单更改在每个更改检测周期创建新的订阅,这会导致巨大的内存泄漏。
将您编写的代码移到 ngOnInit 函数或至少一个只调用一次的函数中。
在这种情况下,您不需要处理 onChange 生命周期,因为您正在监听表单更改本身。
最好创建一个自定义的formGroup的formError。它比你想象的更简单:只需在你的组件中创建一个函数:
requiredIfOneNotEmpty()
{
return (formGroup:FormGroup)=>{
const oneFilled=formGroup.value.street ||
formGroup.value.streetNumber ||
formGroup.value.zipCode
if (!oneFilled)
return null
const error={}
if (!formGroup.value.street)
error.requiredStreet='Street is required';
if (!formGroup.value.streetNumber )
error.requiredStreetNumber='Street number is required'
if (!formGroup.value.zipCode)
error.requiredZipCode:'Zip code is required'
return error
}
}
然后您可以简单地创建表单
formGroup=new FormGroup({
street:new FormControl(null,Validators.maxLength(36)),
streetNumber:new FormControl(null,Validators.maxLength(10)),
zipCode:new FormControl(null,Validators.maxLength(10));
},this.requiredIfOneNotEmpty())
你检查错误使用
<div *ngIf="formGroup.errors?.requiredStreet">Required Street</div>
<div *ngIf="formGroup.errors?.requiredStreetNumber">Required Street Number</div>
<div *ngIf="formGroup.errors?.requiredZipCode">Required Zip Code</div>