Angular 自定义验证器。如何使用给定的 Promise 验证表单字段?
Angular Custom Validators. How to validate a form field using a given Promise?
我需要使用 returns Promise 的方法来验证表单字段。但它永远不会 returns 错误,因为 Promises 是异步的。
这是我的验证器:
static email(usersService: UsersService): ValidatorFn {
return (control: AbstractControl):{ [key: string]: boolean | null } => {
const email = control.value;
if (email) {
usersService.validateUsername(email).then(
(result) => { return result.username ? {emailExists: true} : null }
)
} else {
return null;
}
}}
这是我的 UsersService 方法
validateUsername(username: string): Promise<{"username": string}> {
return this.httpClient.post('/users/username_validation', {"username": username}).pipe(
map((body: {"username": string}) => body),
).toPromise()}
我认为你错过了 return 的承诺,这应该有效
if (email) {
return usersService.validateUsername(email).then( // here in this line
(result) => { return result.username ? {emailExists: true} : null }
)
}
您可以将其重构为
return (control: AbstractControl):Promise<ValidationErrors | null> | Observable<ValidationErrors | null> =>
{
const email = control.value;
return (email && usersService.validateUsername(email).then(
(result) => { return result.username ? {emailExists: true} : null }
)) || null;
}
我需要做的就是像这样使用 AsyncValidator:
validator.ts
import { Injectable } from '@angular/core';
import { AbstractControl, AsyncValidator, ValidationErrors } from '@angular/forms';
import { Observable} from 'rxjs';
import { UsersService } from "@app/users/users.service";
@Injectable({
providedIn: 'root'
})
export class EmailValidator implements AsyncValidator {
constructor( private usersService: UsersService ) { }
validate( control: AbstractControl): Promise<ValidationErrors> | Observable<ValidationErrors> {
const email = control.value;
if (email) {
return this.usersService.validateUsername(email).then(
(result) => {
console.log(result)
return result.username ? {emailExists: true} : null
}
)
} else {
return null;
}
}
}
我需要使用 returns Promise 的方法来验证表单字段。但它永远不会 returns 错误,因为 Promises 是异步的。
这是我的验证器:
static email(usersService: UsersService): ValidatorFn {
return (control: AbstractControl):{ [key: string]: boolean | null } => {
const email = control.value;
if (email) {
usersService.validateUsername(email).then(
(result) => { return result.username ? {emailExists: true} : null }
)
} else {
return null;
}
}}
这是我的 UsersService 方法
validateUsername(username: string): Promise<{"username": string}> {
return this.httpClient.post('/users/username_validation', {"username": username}).pipe(
map((body: {"username": string}) => body),
).toPromise()}
我认为你错过了 return 的承诺,这应该有效
if (email) {
return usersService.validateUsername(email).then( // here in this line
(result) => { return result.username ? {emailExists: true} : null }
)
}
您可以将其重构为
return (control: AbstractControl):Promise<ValidationErrors | null> | Observable<ValidationErrors | null> =>
{
const email = control.value;
return (email && usersService.validateUsername(email).then(
(result) => { return result.username ? {emailExists: true} : null }
)) || null;
}
我需要做的就是像这样使用 AsyncValidator:
validator.ts
import { Injectable } from '@angular/core';
import { AbstractControl, AsyncValidator, ValidationErrors } from '@angular/forms';
import { Observable} from 'rxjs';
import { UsersService } from "@app/users/users.service";
@Injectable({
providedIn: 'root'
})
export class EmailValidator implements AsyncValidator {
constructor( private usersService: UsersService ) { }
validate( control: AbstractControl): Promise<ValidationErrors> | Observable<ValidationErrors> {
const email = control.value;
if (email) {
return this.usersService.validateUsername(email).then(
(result) => {
console.log(result)
return result.username ? {emailExists: true} : null
}
)
} else {
return null;
}
}
}