我正在Angular 8.3.4中做一个Web应用程序。我有一个使用“反应式表单”的表单,并且我想添加“异步验证”以确保输入的名称是唯一的。我已经阅读了很多示例,但是由于某些原因对我不起作用。
服务
export class BrandService {
brands: Observable<BrandId[]>;
}
组件
export class CreateNewComponent {
form: FormGroup;
constructor(
private formBuilder: FormBuilder,
private brandService: BrandService
) {
// Creates a form group
this.form = this.formBuilder.group({
name: ['', Validators.compose([
Validators.required,
Validators.minLength(6),
CustomValidator.unique(this.brandService.brands)
])]
});
}
}
自定义验证器
export class CustomValidator {
static unique(brands: Observable<BrandId[]>) {
return (control: AbstractControl) => {
const name = control.value.toLowerCase();
return brands.pipe(
map(items => items.filter(b => b.name.toLowerCase() === name)),
map(items => items.length ? {unique: false} : null)
);
};
}
}
我正在将服务的Observable从组件传递到CustomValidator。现在,该控件具有:status: "INVALID"
顺便问一下,我应该在unique
方法中显式返回什么?
我的目标是知道该名称是否已经存在于Observable的数组中,以返回控制错误。
答案 0 :(得分:0)
异步验证器应通过另一个数组(或单独)传递,例如
name: [
'',
Validators.compose([ Validators.required, Validators.minLength(6)]),
() => CustomValidator.unique(this.brandService.brands)
]
还要注意,它在一个函数中,我早些时候发现的许多示例都使用in this article之类的bind
,但我更喜欢使用一个函数。
------编辑------ 这是一个有效的例子
@Component({
selector: 'app-new',
templateUrl: './new.component.html',
styleUrls: ['./new.component.css']
})
export class NewComponent {
form: FormGroup;
constructor(
private formBuilder: FormBuilder,
private brandService: BrandService,
) {
const brand = new BrandId();
brand.name = 'abcdef';
this.brandService.brands = of([brand]);
// Creates a form group
this.form = this.formBuilder.group({
name: ['', Validators.compose([
Validators.required,
Validators.minLength(6),
]),
(control) => CustomValidator.unique(this.brandService.brands, control)]
});
}
}
export class CustomValidator {
static unique(brands: Observable<BrandId[]>, control: AbstractControl) {
const name = control.value.toLowerCase();
return brands.pipe(
map(items => items.filter(b => b.name.toLowerCase() === name)),
map(items => items.length ? { unique: false } : null)
);
}
}