【发布时间】:2021-03-11 11:51:41
【问题描述】:
我有一个<input>,用户输入一个在数据库中应该是唯一的值。我想在前端动态检查该值是否唯一。
如果值已经存储在数据库中,我还想显示一条错误消息。
【问题讨论】:
标签: angular validation asynchronous angular-custom-validators
我有一个<input>,用户输入一个在数据库中应该是唯一的值。我想在前端动态检查该值是否唯一。
如果值已经存储在数据库中,我还想显示一条错误消息。
【问题讨论】:
标签: angular validation asynchronous angular-custom-validators
您可以使用自定义异步验证器来执行此操作。假设您要检查名称是否唯一。首先,为异步验证器创建一个新文件:
@Injectable({ providedIn: 'root' })
export class NameValidator {
constructor(private nameService: NameService) { }
CheckNameValidator(): AsyncValidatorFn {
return (control: AbstractControl): Observable<{ [key: string]: boolean } | null> => {
return this.nameService.nameExists(control.value)
.pipe(
map(valueExists => {
if (valueExists) {
return { nameExists: true };
}
return null;
}
)
)
}
}
验证器是一个服务,您可以在其中导入服务 nameService,您可以在其中调用您的 api。如果值存在或不存在,api 必须返回。然后,在控制器中:
export class MainComponent implements OnInit {
constructor(
private fb: FormBuilder,
private nameValidator: NameValidator
) {}
public formGroup: FormGroup;
ngOnInit(): void {
this.formGroup = this.fb.group({
name: ['', [Validators.required, Validators.minLength(3)], [this.nameValidator.CheckNameValidator()]]
}, {updateOn: 'blur'});
}
当您构建表单组时,每个表单控件都可以保存一个值、一个验证器数组和一个异步验证器数组。这就是我调用异步验证器服务的地方。
注意{updateOn: 'blur'},如果你不写这个,检查验证器的更新正在改变,所以你做了太多的api调用。使用 onBlur 完成 api 调用 onblur => 性能提升。
如果你使用有角度的材质,你的视图应该是这样的:
<ng-container [formGroup]="formGroup">
<mat-form-field class="field-full-width">
<input matInput placeholder="Name" formControlName="name">
<mat-error *ngIf="formGroup.controls['name'].errors?.nameExists">This name is already in use</mat-error>
</mat-form-field>
</ng-container>
【讨论】: