我想确认密码,但是当我编写验证程序的逻辑并将其发送到mat-error
时,消息并未显示,但是验证程序正常工作,如何在我的系统中以反应形式修复此刻情况?
export class SignUpComponent implements OnInit {
profileForm: FormGroup;
constructor(
private userService: UserService,
private formBuilder: FormBuilder
) {
this.profileForm = this.formBuilder.group({
name: ['', [Validators.required, Validators.pattern(/^[a-zA-Z0-9_ -]+$/)]],
email: ['', [Validators.required, Validators.pattern(/^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/)]],
password: ['', [Validators.required, Validators.pattern(/^(?=.*[A-Z])(?=.*\d)(.{8,100})$/)]],
passwordConfirm: ['', [Validators.required]]
},
{ validator: this.checkPasswords }
);
}
checkPasswords(group: FormGroup) {
let pass = group.get('password').value;
let confirmPass = group.get('passwordConfirm').value;
return pass === confirmPass ? null : { mismatch: true }
}
ngOnInit() {
}
get name(){
return this.profileForm.get('name');
}
get email(){
return this.profileForm.get('email');
}
get password(){
return this.profileForm.get('password')
}
get passwordConfirm(){
return this.profileForm.get('passwordConfirm')
}
onSubmit() {
console.warn(this.profileForm.value);
this.userService.createUser(this.profileForm.value);
}
}
以html代码
<form class="form-to-submit" [formGroup]="profileForm" (ngSubmit)="onSubmit()">
<div class="form-input-position">
<mat-form-field class="example-full-width" >
<input matInput placeholder="Name" formControlName="name" required>
<mat-icon matSuffix>supervised_user_circle</mat-icon>
<mat-error *ngIf="name.hasError('required')">
Field should be <strong>required</strong>
</mat-error>
<mat-error *ngIf="name.hasError('pattern')">
Field should use <strong>Latin alphabet</strong>
</mat-error>
</mat-form-field>
</div>
<div class="form-input-position">
<mat-form-field class="example-full-width" >
<input matInput placeholder="Email" formControlName="email" required>
<mat-icon matSuffix>email</mat-icon>
<mat-error *ngIf="email.hasError('required')">
Field should be <strong>required</strong>
</mat-error>
<mat-error *ngIf="email.hasError('pattern')">
Use right <strong>email format</strong>
</mat-error>
</mat-form-field>
</div>
<div class="form-input-position">
<mat-form-field class="example-full-width" >
<input matInput type="password" placeholder="Password" formControlName="password" required>
<mat-icon matSuffix>lock</mat-icon>
<mat-error *ngIf="password.hasError('required')">
Field should be <strong>required</strong>
</mat-error>
<mat-error *ngIf="password.hasError('pattern')">
Should be <strong>minimum 8 elements, one uppercase letter, one number</strong>
</mat-error>
</mat-form-field>
</div>
<div class="form-input-position">
<mat-form-field class="example-full-width" >
<input matInput type="password" placeholder="Confirm password" formControlName="passwordConfirm" required>
<mat-icon matSuffix>lock</mat-icon>
<mat-error *ngIf="passwordConfirm.hasError('required')">
Field should be <strong>required</strong>
</mat-error>
{{profileForm.hasError('mismatch')}}
<mat-error *ngIf="profileForm.hasError('mismatch')">
Password <strong>mistmached</strong>
</mat-error>
</mat-form-field>
</div>
<div class="form-input-button">
<button mat-raised-button color="accent" [disabled]="!profileForm.valid" type="submit">Submit</button>
<button mat-raised-button color="warn">Cancel</button>
</div>
</form>
我已经尝试过这种情况(Confirm password validation in Angular 6解决方案),但问题出在错误处:
未捕获的错误:声明的意外值'SignUpComponent'由 模块“ AppModule”。请添加一个@ Pipe / @ Directive / @ Component 注释。
如果我是对的,那是template-driven forms
而不是一种被动的方式
节点
我的app.modul.ts
文件
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { HttpClientModule } from '@angular/common/http';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { SignUpComponent } from './sign-up/sign-up.component';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { MatIconModule,
MatMenuModule,
MatInputModule,
MatButtonModule
} from '@angular/material';
import { LoginComponent } from './login/login.component';
import { HomeComponent } from './home/home.component';
@NgModule({
declarations: [
AppComponent,
SignUpComponent,
LoginComponent,
HomeComponent
],
imports: [
BrowserModule,
FormsModule,
AppRoutingModule,
BrowserAnimationsModule,
MatMenuModule,
MatIconModule,
MatInputModule,
MatButtonModule,
ReactiveFormsModule,
HttpClientModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
节点2
我已阅读https://itnext.io/materror-cross-field-validators-in-angular-material-7-97053b2ed0cf
和这个https://material.angular.io/components/input/overview#changing-when-error-messages-are-shown
此链接介绍了ErrorStateMatcher实现以触摸输入。好吧,我更改了代码
在sign-up.component.ts
export class MyErrorStateMatcher implements ErrorStateMatcher {
isErrorState(control: FormControl | null, form: FormGroupDirective | NgForm | null): boolean {
return control.dirty && form.invalid;
}
}
如果我们开始在输入中键入内容,并且表单本身无效,请声明控件有错误。
在errorMatcher = new MyErrorStateMatcher();
登录中创建对象class SignUpComponent
我在ts文件中的表单看起来像
this.profileForm = this.formBuilder.group({
name: ['', [Validators.required, Validators.pattern(/^[a-zA-Z0-9_ -]+$/)]],
email: ['', [Validators.required, Validators.pattern(/^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/)]],
password: ['', [Validators.required, Validators.pattern(/^(?=.*[A-Z])(?=.*\d)(.{8,100})$/)]],
passwordConfirm: ['']
},
{ validator: this.passwordValidator }
);
}
passwordValidator(form: FormGroup) {
const condition = form.get('password').value !== form.get('verifyPassword').value;
return condition ? { passwordsDoNotMatch: true} : null;
}
最后是html文件
<input matInput type="password" placeholder="Confirm password" formControlName="passwordConfirm" required
[errorStateMatcher]="matcher">
<mat-icon matSuffix>lock</mat-icon>
<mat-error *ngIf="passwordConfirm.hasError('required')">
Field should be <strong>required</strong>
</mat-error>
{{profileForm.hasError('mismatch')}}
<mat-error
*ngIf="profileForm.hasError('passwordsDoNotMatch')">
Field should be <strong>AAAAA</strong>
</mat-error>
<p
*ngIf="profileForm.hasError('passwordsDoNotMatch')">aaaaaaaaaaaaaaaa</p>
但是,我遇到了一个大问题,那就是停止下载表格
compiler.js:2175未捕获的错误:模块'AppModule'声明了意外的值'SignUpComponent'。请添加@ Pipe / @ Directive / @ Component批注。
我已经尝试修复它(添加到@NgModule下一行)
providers: [
{ provide: ErrorStateMatcher, useClass: ShowOnDirtyErrorStateMatcher }
],
但这对我没有帮助
答案 0 :(得分:0)
*更新
要在控件上创建customFormControl,我们使用父级,请参见示例
checkPasswords(): ValidatorFn {
//see that the argument is a FormControl
return (control: FormControl): ValidationErrors => {
//the formGroup is control.parent
const group = control.parent as FormGroup;
//but we must sure that is defined
if (!group) return null;
console.log(group.get("password").value);
let pass = group.get("password").value;
let confirmPass = group.get("passwordConfirm").value;
return confirmPass ? pass === confirmPass ? null : { mismatch: true } : null;
};
}
我们也想在更改密码时进行检查
ngOnInit() {
this.form.get("password").valueChanges.subscribe(() => {
this.form.get("passwordConfirm").updateValueAndValidity();
});
}
看到表格就像
form = new FormGroup({
password: new FormControl("", Validators.required),
passwordConfirm: new FormControl("", [
Validators.required,
this.checkPasswords()
])
});
.html
<form [formGroup]="form" class="example-form">
<mat-form-field class="example-full-width">
<input matInput placeholder="password" formControlName="password">
<mat-error >
required
</mat-error>
</mat-form-field>
<mat-form-field class="example-full-width">
<input matInput placeholder="repeat password" formControlName="passwordConfirm"
>
<mat-error *ngIf="form.get('passwordConfirm').hasError('mismatch')">
must matcher
</mat-error>
<mat-error *ngIf="form.get('passwordConfirm').hasError('required')">
required
</mat-error>
</mat-form-field>
</form>
堆积如山的here
另一种方法是使用自定义的errorStateMatcher
更新2 我说另一种方法是“使用errorStateMatcher”。 erroStateMatcher是一个返回true或false的简单函数。如果返回true,我们的控件将被标记为无效(*)
假设我们有一个类似
的表格form = new FormGroup({
password: new FormControl("", Validators.required),
passwordConfirm: new FormControl("", [
Validators.required,
])
},this.checkPasswords());
看到错误属于formGroup,我们可以创建一个customErrorMatcher,如果控件无效或form.hasError('mismatch`)
,则返回true。export class MyErrorStateMatcher implements ErrorStateMatcher {
isErrorState(control: FormControl | null, form: FormGroupDirective | NgForm | null): boolean {
return !!((control && form.hasError('mismatch') || control.invalid) && control.touched );
}
}
.html
<form [formGroup]="form" class="example-form">
<mat-form-field class="example-full-width">
<input matInput placeholder="password" formControlName="password">
<mat-error >
required
</mat-error>
</mat-form-field>
<!--see that the "errorStateMatcher" is applied to the input "passwordConfirm"-->
<mat-form-field class="example-full-width">
<input matInput placeholder="repeat password" formControlName="passwordConfirm"
[errorStateMatcher]="matcher"
>
<!--here show the error is form.hasError('mismatch')-->
<mat-error *ngIf="form.hasError('mismatch')">
must matcher
</mat-error>
<!--here show the error is form.get('passwordConfirm').hasError-->
<mat-error *ngIf="form.get('passwordConfirm').hasError('required')">
required
</mat-error>
</mat-form-field>
</form>
一如既往,the stackblitz
(*)以stackblitz形式签入.get('passwordConfirm')。invalid