javascript - Angular skjemaer egendefinert validator null return ikke fjerner feil fra skjema


Så jeg har laget en tilpasset validator for å verifisere at bekreftelsespassordet samsvarer med det opprinnelige passordet. Det fungerer fint. Jeg tillater imidlertid at begge feltene kan være tomme siden dette er på en side hvor noen kan endre passordet sitt i innstillingene, noe de selvfølgelig kanskje ikke vil gjøre. Skjemaet bør bli gyldig hvis begge er tomme slik at det kan sendes inn og de andre innstillingene kan oppdateres for profilen deres, men noe merkelig skjer.

Skjemaegenskaper:

passControl = new FormControl('', [
  FormValidation.checkPasswordStrength()
]);

passConfirmControl = new FormControl('', [
]);

profileForm = new FormGroup(
  {
    password: this.passControl,
    passwordConfirm: this.passConfirmControl
  },
  {
    validators: FormValidation.checkPasswordsMatch()
  }
);

Her er min valideringsfunksjon:

static checkPasswordsMatch(): ValidatorFn {
  return (control: AbstractControl): {[key: string]: any} => {
    let passwordCtrl = control.get('password');
    let passwordConfirmCtrl = control.get('passwordConfirm');

    // allow blank for when they don't want to change password
    if (passwordCtrl.value === '' && passwordConfirmCtrl.value === '') {
      console.log('both are blank');
      return null;
    }

    if (passwordCtrl.value !== passwordConfirmCtrl.value) {
      console.log('hit mismatch passwords');
      control.get('passwordConfirm').setErrors( { passwordMatch: true } );
    }

    return null;
  };
}

Så når skjemaet lastes, er det faktisk gyldig og jeg ser begge er tomme. Men hvis du berører passordfeltet og skriver noe, viser det selvsagt at de nå ikke stemmer overens, men når du sletter det du skrev der, viser funksjonen at de igjen begge er tomme, men feilen blir værende og skjemaet forblir ugyldig, med mindre du også berører feltet passwordConfirm og skriver noe der og sletter det. Hva går jeg glipp av?

Svar #1

Du setter feilen på passwordConfirm FormControl, som validatoren din ikke påvirker når den kjører. Hvis du vil at feilen skal forsvinne, må du enten bruke validatoren på den spesifikke FormControl, eller du må sørge for å fjerne feilen fra kontrollen når de tidligere testene lykkes.

Vanligvis vil du returnere feilen innenfor en validator i stedet for å sette den på en spesifikk FormControl. Som du oppdager, med mindre du manuelt fjerner feilen fra FormControl, vil den bli værende. Validatorer vil bare endre feilobjektene til kontrollene de er bundet til.

Vanligvis ville du bare returnere feilen hvis/når den oppstår.

return { passwordMatch: true };

Eller hvis du vil gjøre begge deler og sette FormControl-feilen manuelt også.

// allow blank for when they don't want to change password
if (passwordCtrl.value === '' && passwordConfirmCtrl.value === '') {
  console.log('both are blank');
  control.get('passwordConfirm').setErrors(null);
  return null;
}

if (passwordCtrl.value !== passwordConfirmCtrl.value) {
  console.log('hit mismatch passwords');
  control.get('passwordConfirm').setErrors( { passwordMatch: true } );
  return { passwordMatch: true }
}

Også bare en pirkete pedantisk ting, du bør prøve å gjøre feilene dine logisk lesbare. Så mens du tester om passordet stemmer, antyder det å si passwordMatch: true at passordene stemmer overens. Du kan ha det bedre med å navngi feilene dine etter feilen i stedet for testen, for eksempel: passwordsDoNotMatch: true. Dette leses som om det er en passordmismatch, noe som er en mer nøyaktig fremstilling av problemet som blir presentert gjennom skjemaet.

Relaterte artikler