Javascript 密码确认角材料

Javascript 密码确认角材料,javascript,html,angular,typescript,angular-material,Javascript,Html,Angular,Typescript,Angular Material,我正在用棱角材料对用户进行身份验证。当确认密码与第一次输入的密码不匹配时,我正在尝试获取适当的mat错误以显示 这是我的html: <mat-form-field hintLabel="Minimum 8 Characters" class=""> <mat-label>Password</mat-label> <input

我正在用棱角材料对用户进行身份验证。当确认密码与第一次输入的密码不匹配时,我正在尝试获取适当的mat错误以显示

这是我的html:

 <mat-form-field hintLabel="Minimum 8 Characters" class="">
                            <mat-label>Password</mat-label>
                            <input 
                            matInput 
                            #input 
                            type="password"
                            formControlName="password">
                            <mat-hint align="end">{{input.value?.length || 0}}/8</mat-hint>
                        </mat-form-field>

                        <mat-form-field>
                            <mat-label>Confirm</mat-label>
                            <input 
                            matInput
                            required  
                            type="password"
                            #confirm
                            formControlName="confirmPassword">
                            <mat-error *ngIf="form.get('confirmPassword').invalid || confirmPasswordMismatch">Password does not match</mat-error>
                            </mat-form-field>

理想的效果是,当确认pw为空时,当用户在pw输入中输入文本时显示错误,当两者都有文本但确认与pw不匹配时显示错误

根据您的代码,您似乎没有为confirmPassword字段添加任何验证:
confirmPassword:newformcontrol(null,)
因此,唯一的验证是通过
required
属性进行的。此外,仅当表单控件无效时,表单字段才会显示mat错误。这意味着您不能仅通过使用ngIf强制显示错误。由于该字段上只有
required
验证,因此只有当该字段为空时才会出现错误。要解决此问题,需要为不匹配检查创建一个验证器,并将其添加到confirmPassword表单控件中。或者,当字段更改时,您可以使用
setErrors()
手动向表单控件添加错误,方法是添加输入侦听器,例如(这只是来自内存,可能需要修复):


证实
我是这样解决的:

模板:

  <mat-form-field>
    <input matInput type="password" placeholder="Password" formControlName="password" (input)="onPasswordInput()">
    <mat-error *ngIf="password.hasError('required')">Password is required</mat-error>
    <mat-error *ngIf="password.hasError('minlength')">Password must have at least {{minPw}} characters</mat-error>
  </mat-form-field>

  <mat-form-field>
    <input matInput type="password" placeholder="Confirm password" formControlName="password2" (input)="onPasswordInput()">
    <mat-error *ngIf="password2.hasError('required')">Please confirm your password</mat-error>
    <mat-error *ngIf="password2.invalid && !password2.hasError('required')">Passwords don't match</mat-error>
  </mat-form-field>
验证程序:

export class SignUpFormComponent implements OnInit {

  minPw = 8;
  formGroup: FormGroup;

  constructor(private formBuilder: FormBuilder) { }

  ngOnInit() {
    this.formGroup = this.formBuilder.group({
      password: ['', [Validators.required, Validators.minLength(this.minPw)]],
      password2: ['', [Validators.required]]
    }, {validator: passwordMatchValidator});
  }

  /* Shorthands for form controls (used from within template) */
  get password() { return this.formGroup.get('password'); }
  get password2() { return this.formGroup.get('password2'); }

  /* Called on each input in either password field */
  onPasswordInput() {
    if (this.formGroup.hasError('passwordMismatch'))
      this.password2.setErrors([{'passwordMismatch': true}]);
    else
      this.password2.setErrors(null);
  }
}
export const passwordMatchValidator: ValidatorFn = (formGroup: FormGroup): ValidationErrors | null => {
  if (formGroup.get('password').value === formGroup.get('password2').value)
    return null;
  else
    return {passwordMismatch: true};
};
注意事项:

export class SignUpFormComponent implements OnInit {

  minPw = 8;
  formGroup: FormGroup;

  constructor(private formBuilder: FormBuilder) { }

  ngOnInit() {
    this.formGroup = this.formBuilder.group({
      password: ['', [Validators.required, Validators.minLength(this.minPw)]],
      password2: ['', [Validators.required]]
    }, {validator: passwordMatchValidator});
  }

  /* Shorthands for form controls (used from within template) */
  get password() { return this.formGroup.get('password'); }
  get password2() { return this.formGroup.get('password2'); }

  /* Called on each input in either password field */
  onPasswordInput() {
    if (this.formGroup.hasError('passwordMismatch'))
      this.password2.setErrors([{'passwordMismatch': true}]);
    else
      this.password2.setErrors(null);
  }
}
export const passwordMatchValidator: ValidatorFn = (formGroup: FormGroup): ValidationErrors | null => {
  if (formGroup.get('password').value === formGroup.get('password2').value)
    return null;
  else
    return {passwordMismatch: true};
};
  • 由于从任一密码字段调用
    onPasswordInput()
    ,编辑第一个密码字段(从而使密码确认无效)也会导致密码确认字段中显示不匹配错误
  • 密码确认字段的
    *ngIf=“password2.invalid&&!password2.hasrerror('required')”
    测试确保不会同时显示两条错误消息(“不匹配”和“required”)

您实际上是在验证表单中的两个字段如何相互作用(“密码”和“确认密码”字段)。这被称为“跨域验证”

这意味着,您的自定义验证器不能仅分配给1个字段。需要将自定义验证器分配给公共父级表单

以下是官方记录的最佳实践,用于验证表单中的两个字段如何相互交互

这个代码片段对我很有用

模板:

<form method="post" [formGroup]="newPasswordForm">
  <input type="password" formControlName="newPassword" />
  <input type="password" formControlName="newPasswordConfirm" />
  <div class="err-msg" *ngIf="newPasswordForm.errors?.passwordMismatch && (newPasswordForm.touched || newPasswordForm.dirty)">
        confirm-password does not match password
      </div>
</form>

请注意,对于
passwordMatchValidator
,它位于组件类之外。它不在类中

Henry的答案非常有用(我很惊讶它没有更多的选票),但我对它进行了调整,使其与角度材质控件配合得很好

该调整依赖于
FormGroup
类具有
parent
属性这一事实。使用此属性,您可以将验证消息绑定到密码确认字段,然后在验证器中向上引用该链

public signUpFormGroup:FormGroup=this.formBuilder.group({
电子邮件:[''[Validators.required,Validators.pattern(validation.patterns.email)],
新密码:this.formBuilder.group({
密码:[''[
需要验证器,
Validators.minLength(validation.passwordLength.min),
Validators.maxLength(validation.passwordLength.max)],
confirmPassword:[''[Validators.required,passwordMatchValidator]]
})
});
验证程序如下所示:

export const passwordMatchValidator:ValidatorFn=(formGroup:formGroup):ValidationErrors | null=>{
const parent=formGroup.parent作为formGroup;
如果(!parent)返回null;
返回parent.get('password')。值===parent.get('confirmPassword')。值?
null:{“不匹配”:true};
}
然后表格看起来像这样:


{{'sign-up.password'| translate}}
锁
{{signUpFormGroup.get('newPassword').value.password.length}
/{{max}}
{{'注册。密码错误。必需'|翻译}}
{{'sign-up.password error.min-length'| translate:passwordRestriction.minLength}}
{{'sign-up.password-error.max-length'| translate:passwordRestriction.maxLength}}
{{'注册。确认密码{翻译}
锁
{{'注册。确认密码错误。必需'{翻译}}
{{'注册。密码错误。不匹配'|翻译}}

谢谢,我实际实现了这一点,只要确认是脏的,它就可以工作。当用户仅开始输入pw而未触摸确认输入时,是否有方法显示错误?如果向输入添加自定义ErrorStateMatcher,理论上可以基于任何内容显示错误。脏的情况很常见时出错-请参阅角度文档。
export class Component implements OnInit {
    this.newPasswordForm = new FormGroup({
      'newPassword': new FormControl('', [
        Validators.required,
      ]),
      'newPasswordConfirm': new FormControl('', [
        Validators.required
      ])
    }, { validators: passwordMatchValidator });
}

export const passwordMatchValidator: ValidatorFn = (formGroup: FormGroup): ValidationErrors | null => {
  return formGroup.get('newPassword').value === formGroup.get('newPasswordConfirm').value ?
    null : { 'passwordMismatch': true };
}