[英]Angular 2+, why doesn't material want to show error message?
我想確認密碼,但是當我編寫驗證器的邏輯並將其發送到mat-error
時,消息沒有顯示,但驗證器正常工作,在我的情況下,如何在反應式 forms 中修復這個時刻?
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>
這種情況我已經嘗試過( 在 Angular 6 解決方案中確認密碼驗證)但錯誤的問題是:
未捕獲的錯誤:模塊“AppModule”聲明的意外值“SignUpComponent”。 請添加@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#sharing-when-error-messages-are-shown
這個鏈接告訴了 ErrorStateMatcher 實現來觸摸輸入。 好吧,我改變了我的代碼
在注冊.component.ts
export class MyErrorStateMatcher implements ErrorStateMatcher {
isErrorState(control: FormControl | null, form: FormGroupDirective | NgForm | null): boolean {
return control.dirty && form.invalid;
}
}
如果我們開始在輸入中輸入一些東西,而表單本身是無效的,state 表示控件有錯誤。
創建 object 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 }
],
但這對我沒有幫助
*更新
要在控件上創建 customFormControl,我們使用 parent,看一個例子
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>
這里的堆棧閃電戰
另一種方法是使用自定義 errorStateMatcher
更新 2我說另一種方法是“使用 errorStateMatcher”。 erroStateMatcher 是一個簡單的 function,它返回 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>
一如既往, stackblitz
(*) 簽入 stackblitz form.get('passwordConfirm').invalid
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.