如何根据先前的字段输入角度更改验证

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 的需要

以上是关于如何根据先前的字段输入角度更改验证的主要内容,如果未能解决你的问题,请参考以下文章

React.js:在更改状态的输入字段中单击取消时如何返回先前的状态值[重复]

如何正确验证 HTML 输入中的数字范围? (角度 2)

如何验证空格/空格? [角度 2]

根据先前在同一表单上输入的值自动完成表单字段

如何根据下拉更改 TextArea 验证

Extjs 数字字段问题