it-swarm.com.de

Winkel 4 muss den erforderlichen Validator bedingt entfernen

In Angular 4 App habe ich ein Formularmodell wie folgt:

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

Jetzt möchte ich nur den erforderlichen Prüfer dynamisch aus dem Array der Kontrollprüfer entfernen. Etwas wie das:

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

Diese Frage ist nicht das Duplikat der erwähnten Frage. Mein Fall ist anders. Ich möchte einfach den anderen Validator entfernen, ohne die anderen zu kennen.

19
Ali Shahzad

wenn Sie eine Bestätigung hinzufügen möchten, probieren Sie diese aus.

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

wenn Sie Validatoren entfernen möchten, versuchen Sie es mit diesem.

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

Ich mag es nicht, Validatoren zu löschen und einzustellen, da ich alle statischen Validatoren (Muster, Min, Max usw.) wiederholen muss, nur um einen dynamischen "erforderlichen" Validator zu haben.

Ich benutze einen bedingten 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))
    );
  };
}

Ich kann dann einen statischen Prüfer mit einer dynamischen "erforderlichen" Bedingung kombinieren:

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

Wobei isClientProj() die Bedingungsfunktion ist (Schließung)

3
Alex R

Leider verfügt Angular derzeit nicht über eine removeValidator-Funktion. Alles, was Sie tun können, ist, die Validatoren ohne den zu ändern, den Sie entfernen möchten. Sie müssen also wissen, welche Validatoren Sie behalten möchten, und nicht den, den Sie entfernen möchten. also das:

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

Ist das am nächsten, müssen Sie eine Remove-Funktion. Sie können auch nicht auf die aktuellen Validatoren in einem Formularsteuerelement zugreifen, um zu versuchen, Ihre eigene Remove-Funktion zu schreiben. Das Beste, was Sie tun können, ist, eine eigene Formularsteuerungsprüfungsmanager-Klasse zu schreiben, die die Prüfer eines bestimmten Steuerelements nachverfolgen und für Sie verwalten kann.

1
bryan60

So fügen Sie Validatoren hinzu:

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

oder

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

Um nur den 'Erforderlichen' Prüfer zu entfernen, können Sie die Prüfer zurücksetzen.

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

pdateValueAndValidity legt fest, wie das Steuerelement Änderungen weitergibt, und gibt Ereignisse aus, wenn der Wert und die Prüfer geändert werden

wir können setValidators verwenden, um die Validierung zu entfernen.

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

Ich hatte das gleiche Problem beim Speichern des Eintrags als Entwurf und bereitete die folgende Lösung vor:

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