0

我有一个<input>用户输入一个在数据库中应该是唯一的值的地方。我想在前端动态检查该值是否唯一。

如果值已经存储在数据库中,我还想显示一条错误消息。

4

1 回答 1

1

您可以使用自定义异步验证器来执行此操作。假设您要检查名称是否唯一。首先,为异步验证器创建一个新文件:

@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>
于 2021-03-11T11:51:41.387 回答