我想实现窗体上的自定义验证,这将检查表单输入,并将其与值的阵列,以确保输入值是唯一的。用于比较的阵列来自于可观察到的。然而,当我试图从验证方法访问阵列表现为不确定的,我假设,因为我正在做错误的顺序相对于认购,不过,我可以不知道如何正确地做到这一点。
下面是精简代码,应该表现出什么,我试图做的。我已经与这两者的验证功能,试了一下。我也曾尝试formgroup定义移动到ngOnInit,并进入实际订阅功能,填充allUserNames后直。
export class userComponent implements OnInit {
user: user = new user;
allUserNames: string[];
generalForm = new FormGroup({
userName: new FormControl(
this.user.name, [
Validators.required,
Validators.maxLength(20),
this.UniqueNameValidator
//,this.UniqueNameValidator1(this.alluserNames)
])
})
constructor(private userService: userService) { }
ngOnInit() {
this.subscribeUsers();
}
subscribeUsers(): void {
this.getUsers().subscribe((users) => {
this.allUserNames = Object.keys(users).map(itm => users[itm].name);
})
}
getUsers(): Observable<user[]> {
return this.userService.getUsers();
}
UniqueNameValidator(allUsers: String[]): ValidatorFn {
return (control: AbstractControl): { [key: string]: boolean } | null => {
allUsers.forEach((userName) => {
if (userName === control.value) {
return { 'notUnique': true };
}
});
return null;
}
}
UniqueNameValidator1(control: AbstractControl): { [key: string]: boolean } | null {
this.allUserNames.forEach((userName) => {
if (userName === control.value) {
return { 'notUnique': true };
}
});
return null;
}
}
我希望验证功能比较输入字符串,返回不是唯一的,如果它从allUserNames获得匹配。不过,我不断收到以下错误:
ERROR Error: Uncaught (in promise): TypeError: Cannot read property 'forEach' of undefined
我真的很感激,如果有人可以在正确的方向指向我!
谢谢。
你有一个this
范围的问题。如果你到控制台登录this
,你会看到,它并不指向组件,但你的函数。
这将是一个异步验证一个适当的地方,你在做一个HTTP调用。此外,我建议建立表格时使用FormBuilder
,所以...
generalForm: FormGroup;
constructor(private userService: userService, private fb: FormBuilder) {
this.generalForm = this.fb.group({
userName: [this.user.name,
[Validators.required, Validators.maxLength(20)],
[this.UniqueNameValidator.bind(this)]]
})
}
异步验证的地方作为第三个参数。见我们还使用bind(this)
得到this
的正确范围。
然后验证会是这个样子:
import { of } from 'rxjs';
import { switchMap } from 'rxjs/operators'
UniqueNameValidator(ctrl: AbstractControl) {
return this.userService.getUsers().pipe(
switchMap((users: user[]) => {
// do stuff, and either return error or "of(null)"
})
);