Angular 4 remove required validator conditionally

后端 未结 10 1900
[愿得一人]
[愿得一人] 2021-02-01 01:26

In Angular 4 app I have a form model like this:

this.form = this._fb.group({
    title: [\'\', [Validators.required, Validators.minLength(3), Validators.maxLengt         


        
相关标签:
10条回答
  • 2021-02-01 02:04

    I don't like clearing and setting validators, as I have to repeat all static validators (patterns, min, max, etc.) just to have a dynamic "required" validator.

    I use a conditional validator:

    export function conditionalValidator(condFn: (control: AbstractControl) => boolean,
    validators: ValidatorFn | ValidatorFn[]): ValidatorFn {
      return (control) => {
        if (!condFn(control)) {
          return null;
        }
    
        if (!Array.isArray(validators)) {
          return validators(control);
        }
    
        return validators.map(v => v(control)).reduce((errors, result) =>
          result === null ? errors :
            (Object.assign(errors || {}, result))
        );
      };
    }
    

    I can then mix a static validator with a dynamic "required" condition:

    this.fb.group({name: ['', [Validators.minLength(4),
                     conditionalValidator(this.isClientProj, Validators.required)]]}
    

    Where isClientProj() is the condition function (closure)

    0 讨论(0)
  • 2021-02-01 02:09

    Unfortunately Angular doesn't have a removeValidator capability at this point in time. All you can do is re-set the validators without the one you want to remove, so you need to know which validators you want to keep rather than which one you want to remove. so this:

    this.form.get('title').setValidators([Validators.minLength(3), Validators.maxLength(50)]);
    

    Is the closest you have to a remove function. You can't access the current validators on a formcontrol either to try and write your own remove function. The best you could do is write your own form control validation manager class that can keep track of the validators on a given control and manage them for you.

    0 讨论(0)
  • 2021-02-01 02:09

    I had the same problem with saving entry as draft and prepared the following solution:

    @Component({
        // ...
    })
    export class FormComponent{
        form: FormGroup;
    
        constructor(private fb: FormBuilder){
            this.form = this.fb.group({
                name: ['', Validators.required, Validators.maxLength(20)],
                description: ['', Validators.required, Validators.maxLength(200)],
                address: this.fb.group({
                    line1: ['', Validators.required, Validators.maxLength(100)],
                    line2: ['', Validators.maxLength(100)]
                })
            });
        }    
    
        validateDraft(formElement: FormGroup | FormArray | FormControl): boolean {
            let result = true;
    
            Object.keys(formElement.controls).forEach(field => {
                const control = formElement.get(field);
    
                if(control instanceof FormControl) {
                    control.markAsTouched({ onlySelf: true });
    
                    if(control.errors && control.errors['required']) {
                        control.markAsUntouched({ onlySelf: true });
                    }
                    else if(control.invalid) {
                        result = false;
                    }
                } else if (control instanceof FormArray) {
                    if (!this.validateDraft(control)) {
                        result = false;
                    } 
                }else if (control instanceof FormGroup) {
                    if (!this.validateDraft(control)) {
                        result = false;
                    }   
                }
            });
        }
    
        saveDraft(){
            if(this.validateDraft(this.form)){
                //save draft - ignore required errors
            }
        }
    
        save(){
            if(this.form.valid){
                //save
            }
        }
    }
    
    0 讨论(0)
  • 2021-02-01 02:10

    we can use setValidators to remove validation.

    this.form.get('title').setValidators(null); 
    this.form.get('title').setErrors(null); 
    
    0 讨论(0)
  • 2021-02-01 02:10

    you can use this to clear validation from reactive form

    this.form.controls['title'].clearValidators(); this.form.controls['title'].updateValueAndValidity();

    you can use this to add validation in reactive form

    this.form.controls['title'].setValidators([Validators.required]); this.form.controls['title'].updateValueAndValidity();

    0 讨论(0)
  • 2021-02-01 02:11
    this.fromName.get("formControlName").setValidators([Validators.required]);//setting validation
    this.fromName.get("formControlName").setErrors({'required':true});//error message
    this.fromName.updateValueAndValidity();//update validation
    
    
    this.fromName.get("formControlName").clearValidators([Validators.required]);//clear validation
    this.fromName.get("formControlName").setErrors(null);//updating error message
    this.fromName.updateValueAndValidity();//update validation
    
    0 讨论(0)
提交回复
热议问题