Angular 11 表单无需创建 formGroup 或使用 formBuilder 即可确认密码字段 希望这有帮助:)

问题描述

HTML 密码和确认密码表单字段集:

  <mat-form-field>
    <mat-label>{{ 'PAGES.LOGIN.PASSWORD' | translate }}</mat-label>
    <input #registerPasswordField matInput title=" " [type]="hide ? 'password' : 'text'" [formControl]="password" required (keyup.enter)="registerConfirmField.focus()">
    <button mat-icon-button matSuffix (click)="hide = !hide" [attr.aria-label]="'Hide password'" [attr.aria-pressed]="hide">
      <mat-icon>{{hide ? 'visibility_off' : 'visibility'}}</mat-icon>
    </button>
    <mat-error *ngIf="password.invalid && password.errors?.pattern">{{ 'PAGES.REGISTER.PASSWORD_INVALID' | translate }}</mat-error>
    <mat-error *ngIf="password.invalid && !password.errors?.pattern">{{ 'PAGES.LOGIN.PASSWORD_required' | translate }}</mat-error>
  </mat-form-field>
  <mat-form-field>
    <mat-label>{{ 'PAGES.REGISTER.CONFIRM' | translate }}</mat-label>
    <input #registerConfirmField matInput title=" " [type]="hide ? 'password' : 'text'" [formControl]="confirmPassword" required (keyup.enter)="loginButton.focus(); register()">
    <button mat-icon-button matSuffix (click)="hide = !hide" [attr.aria-label]="'Hide password'" [attr.aria-pressed]="hide">
      <mat-icon>{{hide ? 'visibility_off' : 'visibility'}}</mat-icon>
    </button>
    <mat-error *ngIf="confirmPassword.errors?.pattern">{{ 'PAGES.REGISTER.CONFIRM_MISMATCH' | translate }}</mat-error>
    <mat-error *ngIf="confirmPassword.invalid">{{ 'PAGES.REGISTER.CONFIRM_required' | translate }}</mat-error>
  </mat-form-field>

使用以下 TS 端表单字段声明:

password = new FormControl("",[
    Validators.required,Validators.pattern("^((?=\\S*?[A-Z])(?=\\S*?[a-z])(?=\\S*?[0-9]).{8,255})\\S$")
])
confirmPassword = new FormControl("",confirmEquals(this,this.password) //pseudocode,obvIoUsly this won't work
])

我正在尝试为此做一些事情,我只是检查 password.value 和 confirmPassword.value 之间的相等。

我无法用 Validators.pattern() 做到这一点(我不明白为什么 Validators.pattern(this.password.value) 不起作用。文档说它也接受一个字符串在这种情况下,它在前面附加 ^ 并在后面附加 $,基本上它只对那个字符串进行正则表达式。它应该工作。但这个验证器永远不会被触发)

我已经看到大量有关密码确认问题的 stackoverflow 问题,但对我来说没有一个看起来干净或简洁(但最重要的是最新的)。

我发现了这个旧的弃用代码示例:

ngOnInit() {
    this.registerForm = this.formBuilder.group({
        firstName: ['',Validators.required],lastName: ['',email: ['',[Validators.required,Validators.email]],password: ['',Validators.minLength(6)]],confirmPassword: ['',Validators.required]
    },{
        validator: MustMatch('password','confirmPassword')
    });
}

这表明 angular 在某一时刻确实费心去实现一个函数来达到这种效果

但据我所知它还没有转移到新的 AbstractControl CLASS

字段“验证器”存在于 FormGroup 的新语法中,但我更喜欢较新的语法,在这种语法中,您不声明整个表单,而只声明每个字段,如新的 angular-material 文档中所示。

现在似乎不鼓励使用 FormBuilder

并且我希望我的方法是 KISS 和高性能的,并且在句法上简洁。

是否有可能进行密码确认(以干净、现代的方式)而无需在公共 formGroup 下管理两个 formControl?

我会接受这是一种糟糕的方法,但我想知道为什么以及“Angular 11”的做法是什么(答案需要跟上当前的最佳实践)。

编辑:我一直在读这个:Reference - Password Validation

以及对此的评论https://stackoverflow.com/a/12806002/4770754

不过,我必须创建自己的注册

解决方法

使用 custom validator 你可以做到。尝试如下,

app.component.ts

  password = new FormControl("",[
    Validators.required,Validators.pattern(
      "^((?=\\S*?[A-Z])(?=\\S*?[a-z])(?=\\S*?[0-9]).{8,255})\\S$"
    )
  ]);
  confirmPassword = new FormControl("",this.confirmEquals() 
  ]); 

  confirmEquals(): ValidatorFn {
    return (control: AbstractControl): { [key: string]: any } | null =>  
        control.value?.toLowerCase() === this.passwordValue.toLowerCase() 
            ? null : {noMatch: true};
  }

  get passwordValue() {
    return this.password.value;
  }

app.component.html

    <mat-form-field class="example-full-width">
        <input matInput placeholder="Password" [formControl]="password"/>
        <mat-error *ngIf="password.dirty && password.errors?.pattern">
            <strong>Pattern Wrong</strong>
        </mat-error>
    </mat-form-field>
    <mat-form-field class="example-full-width">
        <input matInput placeholder="Confirm Password" [formControl]="confirmPassword"/>
        <mat-error *ngIf="confirmPassword.dirty && confirmPassword.errors?.noMatch">
            <strong>Password</strong> and <strong>Confirm Password</strong> must be same
        </mat-error>
    </mat-form-field>

stackblitz 工作示例:https://stackblitz.com/edit/angular-ztqtaz?file=src/app/app.component.html

希望这有帮助:)