如何根据先前的字段输入角度更改验证
Posted
技术标签:
【中文标题】如何根据先前的字段输入角度更改验证【英文标题】:How can I change the validations based on previous field input angular 【发布时间】:2022-01-22 02:49:45 【问题描述】:我有两个角度反应形式的字段。我需要验证第二个字段并根据选择的第一个字段选项显示错误消息。
第一场:
<label>ID proof </b><span class="asterisk">*</span></label>
<mat-form-field appearance="outline">
<mat-select name="idproofs" placeholder="IDProof name" required formControlName="idProof" class="form-control">
<mat-option *ngFor="let idproof of idproofs" [value]="idproof.value">
idproof.viewValue
</mat-option>
</mat-select>
</mat-form-field>
字段二:
<label>ID proof number </b><span class="asterisk">*</span></label>
<mat-form-field appearance="outline">
<input matInput placeholder="ID Proof Number" required formControlName="idFroofNumber" class="form-control">
<mat-error *ngIf="PGroup.controls['idProofNumber'].hasError('required')">
ID proof number is required!
</mat-error>
</mat-form-field>
示例如果我选择选项作为 Adhaar 号码,则在第二个字段中验证只能是最大长度为 12 位字符的数字。
如果我选择 PAN 编号,那么只有验证将是最大长度为 10 个字符的字母数字。因此,如果我也可以提供错误消息验证。我怎样才能做到这一点
EDIT添加了ts formcontrol
this.PGroup = this._formBuilder.group(
idProof: ['', Validators.required],
idProofNumber: ['', [Validators.required,Validators.pattern(/^[\w\s]+$/)]]
);
【问题讨论】:
【参考方案1】:你能提供你的 ts 代码吗?我看到您将 ngModel 与 formControlName 结合使用,我认为它是将反应式方法与模板驱动方法相结合。 无论如何,这是我的建议。 以这种方式使用响应式方法,(仅建议,您可以根据自己的喜好获得想法并实施)
// attr declarations
fieldOne = new FormControl('',[]); // initial value and validators inside array
fieldTwo = new FormControl('', []); // initialValue and validators
// ngOnInit
fieldOne.valueChanges.
.pipe(
debounceTime(100), // dalay after every change to update your validations
distinctUntilChanged(), // only update validators when value change
tap(value =>
// depend on your options you can use switch here
if(value === 'Adhaar number')
this.fieldTwo.setValidators([Validators.required,Validators.maxLength(12)]);
this.fieldTwo.updateValueAndValidity();
else
if(value === 'PAN number')
this.fieldTwo.setValidators([Validators.required,Validators.maxLength(10)]);
this.fieldTwo.updateValueAndValidity();
else
this.fieldTwo.setValidators([Validators.required]);
this.fieldTwo.updateValueAndValidity();
)
)
.subscribe()
根据您可能出现的错误更新您的 html。
您也可以将 formGroup 与两个字段一起使用,而不是单独的 formControls,并且只需将订阅从 this.fieldOne.valueChanges 更改为 this.form.get('fieldOne').valueChanges
请记住取消订阅此订阅。我建议 https://www.npmjs.com/package/@ngneat/until-destroy【讨论】:
好的,在这种情况下,使用 this.PGroup.get('yourField') 根据订阅或更新验证器更新我的代码 我没有使用 ngModel 在我忘记删除它之前。我只使用反应形式。我正在 EDIT 中更新我的问题,提供 ts 文件控制器。我只使用组。那么您可以根据我根据您的建议添加的组进行修改吗?Validators.maxLength()
不工作。【参考方案2】:
我认为你可以这样做,
假设你有一个名为 AppComponent 的组件,
import Component from '@angular/core';
import
FormBuilder,
FormGroup,
FormControl,
ValidationErrors,
AbstractControl,
ValidatorFn
from '@angular/forms';
@Component(
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
)
export class AppComponent
title = '***-examples';
panelOpenState = false;
idproofOptions: string[] = ['Aadhar','PAN'];
idproofsForm: FormGroup;
get idproofsFormControl(): FormControl
// debugger
return this.idproofsForm.controls['idproofs'] as FormControl;
get idproofsInputFormControl(): FormControl
// debugger
return this.idproofsForm.controls['idproofsInput'] as FormControl;
idproofInputAadharValidation(): ValidatorFn
return (control: AbstractControl): ValidationErrors | null =>
// debugger
const pattern = new RegExp("^[0-9]10$");
if (pattern.test(control.value))
return null;
else
return
aadharError: 'Aadhar number is not correct'
;
;
idproofInputPANValidation(): ValidatorFn
return (control: AbstractControl): ValidationErrors | null =>
// debugger
const pattern = new RegExp("^[a-zA-Z0-9]+$");
if (pattern.test(control.value))
return null;
else
return
panError: 'PAN number is not correct'
;
;
constructor(
private fb: FormBuilder
)
this.idproofsForm = new FormGroup(
idproofs: new FormControl(''),
idproofsInput: new FormControl('')
);
ngOnInit()
this.idproofsForm.valueChanges.subscribe(
field =>
// debugger
console.log(this.idproofsForm.controls['idproofsInput']);
if (field['idproofs'] && field['idproofs'] === 'PAN')
this.idproofsInputFormControl.clearValidators();
this.idproofsInputFormControl.setValidators(this.idproofInputPANValidation());
else if (field['idproofs'] && field['idproofs'] === 'Aadhar')
this.idproofsInputFormControl.clearValidators();
this.idproofsInputFormControl.setValidators(this.idproofInputAadharValidation());
// debugger
);
您的 HTML 可能如下所示,
<label>ID proof<span class="asterisk">*</span></label>
<mat-form-field appearance="outline">
<mat-select [formControl]="idproofsFormControl" name="idproofs" placeholder="IDProof name" required class="form-control">
<mat-option *ngFor="let idproof of idproofOptions" [value]="idproof">
idproof
</mat-option>
</mat-select>
</mat-form-field>
<br/>
<!-- idproofsInputFormControl|json -->
<label>ID proof number<span class="asterisk">*</span></label>
<mat-form-field appearance="outline">
<input matInput placeholder="ID Proof Number" required [formControl]="idproofsInputFormControl" class="form-control">
<mat-error *ngIf="idproofsInputFormControl.errors">
idproofsInputFormControl.errors['aadharError']
</mat-error>
</mat-form-field>
在屏幕截图中查看以下错误
注意:我的建议是您不要使用 ngModel,反应式方法要好得多,您可能需要稍微更改此代码以满足您的要求,但我相信它应该会有所帮助
【讨论】:
我没有使用 ngModel。我忘了从代码中删除它。虽然我会试试你的,但 Adhaar 的验证在哪里? Adhaar 仅由数字组成。如果我明天添加驾驶执照或选民卡,那么这些将再次是字母数字。在那种情况下? 查看这两个验证函数idproofInputAadharValidation
和 idproofInputPANValidation
还请注意,此代码只是指示您如何获得所需的答案可能不完全适合您的账单
明白。谢谢,我试试看
只是一个细节,如果您订阅整个表单的所有更改,请注意这种方法,因为每次更改 idproofsInput 字段时,您也会执行该订阅,我认为您应该评估修改这个仅订阅 idProof 更改的解决方案
是的,没错,但正如我所提到的,它需要进行小修改以适应确切的要求,但这非常接近 @OptimistRohit 的需要以上是关于如何根据先前的字段输入角度更改验证的主要内容,如果未能解决你的问题,请参考以下文章