Angular 4 удалить требуемый валидатор условно

В приложении Angular 4 у меня есть модель формы следующим образом:

this.form = this._fb.group({
    title: ['', [Validators.required, Validators.minLength(3), Validators.maxLength(50)]],
    description: ['', [Validators.required, Validators.minLength(3)]]
});

Теперь я хочу, чтобы динамически удалять только необходимый валидатор из массива проверки правителей. Что-то вроде этого:

saveDraft() {
    this.form.controls['title'].removeValidator('required'); //Just a fake implementation for demonstration
}

Этот вопрос не является дубликатом упомянутого вопроса. Мое дело другое. Я просто хочу удалить необходимый валидатор, неосознанно, другие.

Ответ 1

если вы хотите добавить подтверждение, попробуйте этот.

saveDraft() {
   this.form.get('title').setValidators([Validators.required, Validators.minLength(3)]);
   this.form.get('title').updateValueAndValidity();
}

если вы хотите удалить валидаторы, попробуйте это.

saveDraft() {
 this.form.get('title').clearValidators();
 this.form.get('title').updateValueAndValidity();
}

Ответ 2

Я не люблю очищать и устанавливать валидаторы, так как мне приходится повторять все статические валидаторы (шаблоны, минимальные, максимальные и т.д.), Чтобы иметь динамический "требуемый" валидатор.

Я использую условный валидатор:

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))
    );
  };
}

Затем я могу смешать статический валидатор с динамическим "обязательным" условием:

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

Где isClientProj() - функция условия (замыкание)

Ответ 3

К сожалению, на данный момент Angular не имеет возможности removeValidator. Все, что вы можете сделать, это переустановить валидаторы без того, который вы хотите удалить, поэтому вам нужно знать, какие валидаторы вы хотите сохранить, а не какой вы хотите удалить. так вот:

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

Является ли вы ближе всего к функции удаления. Вы не можете получить доступ к текущим валидаторам в formcontrol, чтобы попытаться написать свою собственную функцию удаления. Лучшее, что вы можете сделать, - это написать свой собственный класс менеджера проверки элементов управления, который может отслеживать средства проверки для данного элемента управления и управлять ими за вас.

Ответ 4

У меня была та же проблема с сохранением записи, как у черновика, и я подготовил следующее решение:

@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
        }
    }
}

Ответ 5

Чтобы добавить валидаторы:

this.form = this._fb.group({
    title: ['', [Validators.required, Validators.minLength(3), Validators.maxLength(50)]],
    description: ['', [Validators.required, Validators.minLength(3)]]
});

или

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

Чтобы удалить только "обязательный" валидатор, вы можете сбросить валидаторы.

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

updateValueAndValidity определяет, как элемент управления распространяет изменения и генерирует события при изменении значения и валидаторов

Ответ 6

saveDraft() {
   this.form.get('title').setValidators([Validators.required, Validators.minLength(3)]);
   this.form.get('title').updateValueAndValidity();
}

saveDraft() {
 this.form.get('title').clearValidators();
 this.form.get('title').updateValueAndValidity();
}

Ответ 7

Если вы удалите подтверждение, попробуйте это

saveDraft() {
    this.form.controls['title'].setValidators([ Validators.minLength(3), Validators.maxLength(50)]);    
    this.form.controls['title'].updateValueAndValidity();
}

если вам нужно добавить подтверждение

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

Ответ 8

мы можем использовать setValidators для удаления проверки.

this.form.get('title').setValidators(null); 
this.form.get('title').setErrors(null);