【发布时间】:2020-10-24 00:00:40
【问题描述】:
我为我的注册表单创建了一个 asyc 验证器,并将其连接到我的 express 应用程序以便它返回正确的响应,现在我处于所有表单控件都有效但表单本身不有效的最后一步得到验证并且提交按钮保持禁用状态,这是我的代码
register.component.ts
import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { AuthService } from '../auth.service';
import { UniqueEmail } from '../validators/unique-email';
@Component({
selector: 'app-register',
templateUrl: './register.component.html',
styleUrls: ['./register.component.scss'],
})
export class RegisterComponent implements OnInit{
registerForm: FormGroup
constructor(
private fb: FormBuilder,
private auth: AuthService,
private uniqueEmail: UniqueEmail
) {}
ngOnInit(){
this.registerForm = this.fb.group({
firstName: [null, [Validators.required, Validators.minLength(2)]],
lastName: [null, [Validators.required, Validators.minLength(2)]],
email: [
null,
[Validators.required, Validators.email],
this.uniqueEmail.validateEmailNotTaken.bind(this.uniqueEmail)
],
phoneNumber: [null, Validators.required],
password: [null, [Validators.required, Validators.minLength(8)]],
});
this.registerForm.valueChanges.subscribe(data => {
const invalid = [];
const controls = this.registerForm.controls;
for (const name in controls) {
if (controls[name].invalid) {
invalid.push(name);
}
}
console.log (invalid);
console.log(this.registerForm.valid)
});
}
onSubmit() {
this.auth.register(this.registerForm.value).subscribe(console.log);
}
}
register.component.html
<form [formGroup]="registerForm" (ngSubmit)="onSubmit()">
<mat-card class="shipping-card">
<mat-card-header>
<mat-card-title>Manager Registration</mat-card-title>
</mat-card-header>
<mat-card-content>
<div class="row">
<div class="col">
<mat-form-field class="full-width">
<input
matInput
placeholder="First name"
formControlName="firstName"
type="text"
/>
<mat-error
*ngIf="registerForm.controls['firstName'].hasError('minlength')"
>
min length is 2 characters
</mat-error>
<mat-error
*ngIf="registerForm.controls['firstName'].hasError('required')"
>
First name is <strong>required</strong>
</mat-error>
</mat-form-field>
</div>
<div class="col">
<mat-form-field class="full-width">
<input
matInput
placeholder="Last name"
formControlName="lastName"
type="text"
/>
<mat-error
*ngIf="registerForm.controls['lastName'].hasError('minlength')"
>
min length is 2 characters
</mat-error>
<mat-error
*ngIf="registerForm.controls['lastName'].hasError('required')"
>
Last name is <strong>required</strong>
</mat-error>
</mat-form-field>
</div>
</div>
<div class="row">
<div class="col">
<mat-form-field class="full-width">
<input
matInput
placeholder="Email"
formControlName="email"
type="email"
/>
<mat-error
*ngIf="registerForm.controls['email'].hasError('required')"
>
Email is <strong>required</strong>
</mat-error>
<mat-error
*ngIf="registerForm.controls['email'].hasError('emailTaken')"
>
this email is used before
</mat-error>
<mat-error *ngIf="registerForm.controls['email'].hasError('email')">
please enter a valid email
</mat-error>
</mat-form-field>
</div>
<div class="col">
<mat-form-field class="full-width">
<input
matInput
placeholder="Phone Number"
formControlName="phoneNumber"
type="text"
/>
<mat-error
*ngIf="registerForm.controls['phoneNumber'].hasError('required')"
>
Phone Number is <strong>required</strong>
</mat-error>
</mat-form-field>
</div>
</div>
<div class="row">
<div class="col">
<mat-form-field class="full-width">
<input
matInput
placeholder="Password"
formControlName="password"
type="password"
/>
<mat-error
*ngIf="registerForm.controls['password'].hasError('required')"
>
Password is <strong>required</strong>
</mat-error>
<mat-error
*ngIf="registerForm.controls['password'].hasError('minlength')"
>
min length is 8 characters
</mat-error>
</mat-form-field>
</div>
<div class="col"></div>
</div>
</mat-card-content>
<mat-card-actions>
<button
mat-raised-button
color="primary"
type="submit"
[disabled]="!registerForm.valid"
>
Submit
</button>
</mat-card-actions>
</mat-card>
</form>
auth.service.ts
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { map } from 'rxjs/operators';
import { environment } from 'src/environments/environment';
@Injectable({
providedIn: 'root',
})
export class AuthService {
constructor(private http: HttpClient) {}
registerUrl = `${environment.apiUrl}/api/manager/register`;
loginUrl = `${environment.apiUrl}/api/manager/login`;
checkEmailNotTakenUrl = `${environment.apiUrl}/api/manager/unique-email`;
register(formInfo) {
return this.http.post(this.registerUrl, formInfo);
}
login(formInfo) {
return this.http.post(this.loginUrl, formInfo).pipe(
map((result) => {
localStorage.setItem('access_token', result['token']);
return result;
})
);
}
logout() {
localStorage.removeItem('access_token');
}
public get loggedIn(): boolean {
return localStorage.getItem('access_token') !== null;
}
checkEmailNotTaken(email) {
return this.http.post(this.checkEmailNotTakenUrl, { email: email });
}
}
unique-email.ts
import { AbstractControl } from '@angular/forms';
import { map, tap } from 'rxjs/operators';
import { AuthService } from '../auth.service';
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root',
})
export class UniqueEmail {
constructor(private auth: AuthService) {}
validateEmailNotTaken(control: AbstractControl) {
return this.auth.checkEmailNotTaken(control.value).pipe(
tap(console.log),
map((res) => {
return res == { emailTaken: true } ? null : { emailTaken: true };
}),
tap(console.log),
);
}
}
这张照片总结了数组包含无效控件的问题,布尔值表示表单的有效性 app inteface
【问题讨论】:
标签: angular validation angular-forms