Angular 11 个表单确认密码字段,无需创建 formGroup 或使用 formBuilder
Angular 11 forms confirm password field without making a formGroup or using 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("", [
Validators.required,
confirmEquals(this, this.password) //pseudocode, obviously this won't work
])
我正在尝试为此做一些事情,我只是检查 password.value 和 confirmPassword.value 之间的相等。
我无法使用 Validators.pattern() 执行此操作(我不明白为什么 Validators.pattern(this.password.value) 不起作用。文档说它还接受一个字符串,在这种情况下,它在前面附加 ^ 并在后面附加 $,基本上它只对那个字符串进行正则表达式。它应该工作。但是这个验证器永远不会被触发)
我已经看到大量关于密码确认问题的 Whosebug 问题,但 none 对我来说似乎干净或简洁(但最重要的是最新的)。
我找到了这个旧的已弃用代码示例:
ngOnInit() {
this.registerForm = this.formBuilder.group({
firstName: ['', Validators.required],
lastName: ['', Validators.required],
email: ['', [Validators.required, Validators.email]],
password: ['', [Validators.required, Validators.minLength(6)]],
confirmPassword: ['', Validators.required]
}, {
validator: MustMatch('password', 'confirmPassword')
});
}
这表明 angular 曾经费心去实现一个功能来达到这个效果。
但据我所知,它还没有移到新的 AbstractControl CLASS
字段“验证器”存在于 FormGroup 的新语法中,但我更喜欢更新的语法,其中您不声明整个表单而只声明每个字段,如新 [=56= 中所示]-material 文档。
现在似乎不鼓励使用 FormBuilder。
我希望我的方法是 KISS 和高效的,并且语法简洁。
是否可以在不将两个 formControl 放在一个公共 formGroup 下的情况下进行密码确认(以干净、现代的方式)?
我承认这是一个糟糕的方法,但我想知道为什么以及“Angular 11”的做法是什么(答案需要与当前最佳实践)。
编辑:我一直在读这个:
以及对此的评论:
但我现在必须创建自己的注册。
有了 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("", [
Validators.required,
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
希望这对您有所帮助:)
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("", [
Validators.required,
confirmEquals(this, this.password) //pseudocode, obviously this won't work
])
我正在尝试为此做一些事情,我只是检查 password.value 和 confirmPassword.value 之间的相等。
我无法使用 Validators.pattern() 执行此操作(我不明白为什么 Validators.pattern(this.password.value) 不起作用。文档说它还接受一个字符串,在这种情况下,它在前面附加 ^ 并在后面附加 $,基本上它只对那个字符串进行正则表达式。它应该工作。但是这个验证器永远不会被触发)
我已经看到大量关于密码确认问题的 Whosebug 问题,但 none 对我来说似乎干净或简洁(但最重要的是最新的)。
我找到了这个旧的已弃用代码示例:
ngOnInit() {
this.registerForm = this.formBuilder.group({
firstName: ['', Validators.required],
lastName: ['', Validators.required],
email: ['', [Validators.required, Validators.email]],
password: ['', [Validators.required, Validators.minLength(6)]],
confirmPassword: ['', Validators.required]
}, {
validator: MustMatch('password', 'confirmPassword')
});
}
这表明 angular 曾经费心去实现一个功能来达到这个效果。
但据我所知,它还没有移到新的 AbstractControl CLASS
字段“验证器”存在于 FormGroup 的新语法中,但我更喜欢更新的语法,其中您不声明整个表单而只声明每个字段,如新 [=56= 中所示]-material 文档。
现在似乎不鼓励使用 FormBuilder。
我希望我的方法是 KISS 和高效的,并且语法简洁。
是否可以在不将两个 formControl 放在一个公共 formGroup 下的情况下进行密码确认(以干净、现代的方式)?
我承认这是一个糟糕的方法,但我想知道为什么以及“Angular 11”的做法是什么(答案需要与当前最佳实践)。
编辑:我一直在读这个:
以及对此的评论:
但我现在必须创建自己的注册。
有了 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("", [
Validators.required,
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