gpt4 book ai didi

javascript - 响应式(Reactive)表单中的 Angular2 通用异步验证器

转载 作者:行者123 更新时间:2023-12-04 10:19:12 25 4
gpt4 key购买 nike

我有一个 react 形式和一个必须唯一的表单控件:

this.form = new FormGroup({
name: new FormControl(this.initialValue, [
Validators.required,
], this._uniqueNameValidator.bind(this)),
});

我编写了一个异步验证器,它从我的应用服务中调用一个方法:

private _uniqueNameValidator(control: FormControl) {
const value = control.value.trim();
if (value === '' || value === this.initialValue) {
return of(null);
}
control.markAsTouched();
return timer(500).pipe(
switchMap(() => {
return this._appService.validateName(value, this.selectedGroupId);
}),
map(response => {
return response ? {nameTaken: true} : null;
}),
catchError(() => {
return of(null);
})
);
}

服务方式是简单的http GET返回 boolean值(value):
validateName(name: string, groupId: number): Observable<boolean> {
// ...
return this._http.get<boolean>(url);
}

工作示例: https://stackblitz.com/edit/angular-8kedup

现在,在我的应用程序中有许多其他表单,其中的控件必须是唯一的。唯一性是异步检查的,但在其他服务方法和其他路由中。
我不想在每个需要异步验证器以实现唯一性的组件中复制验证器的代码。

问题 :
我想编写一个通用验证器,它将必须调用的服务方法作为参数,以确定该值是否唯一,以及初始表单值。

我写了以下函数:

export function UniqueAsyncValidator(fn: any, initialValue: string): AsyncValidatorFn {
return (control: AbstractControl): Promise<ValidationErrors | null> | Observable<ValidationErrors | null> => {
const value = control.value.trim();
if (value === '' || value === initialValue) {
return of(null);
}
control.markAsTouched();
return timer(500).pipe(
switchMap(() => {
return fn(value);
}),
map(response => {
return response ? {nameTaken: true} : null;
}),
catchError(() => {
return of(null);
})
);
};
}

和表格定义:
    this.form = new FormGroup({
name: new FormControl(this.initialValue, [
Validators.required,
], UniqueAsyncValidator(this._appService.validateName, this.initialValue).bind(this)),
});

似乎调用了服务方法,但服务方法中的上下文( this )未定义:
validateName(name: string, groupId: number): Observable<boolean> {
// ....
console.log( 'this: ', this ); // -> returns undefined
return this._http.get<boolean>(url);
}

示例: https://stackblitz.com/edit/angular-sbbgc8

谢谢!

最佳答案

您在两个版本中都没有进行相同的函数调用。您的服务功能需要 groupId .您应该在回调中使用此参数调用服务。

const uniqueValidator = UniqueAsyncValidator(
value => this._appService.validateName(value, this.selectedGroupId),
this.initialValue).bind(this);

this.form = new FormGroup({
name: new FormControl(this.initialValue, [
Validators.required,
], uniqueValidator)
});

当您创建 UniqueAsyncValidator 的实例时,您正在传递一个回调。这允许您重用验证器内部的逻辑,并注入(inject)将进行调用的函数。
value => this._appService.validateName(value, this.selectedGroupId)

这是箭头函数语法。它只是声明一个接受一个参数的匿名函数 - value (这是由您的验证器传入的) - 并返回 this._appService.validateName(value, this.selectedGroupId) .

演示: https://stackblitz.com/edit/angular-ynmzyu

关于javascript - 响应式(Reactive)表单中的 Angular2 通用异步验证器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60945644/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com