我在使自定义异步验证器工作时遇到问题。我的方法如下。
组件:
import {Component, OnInit} from "@angular/core";
import {FormGroup, FormBuilder, Validators} from "@angular/forms";
import {User} from "./user";
import {EmailValidators} from "./emailValidators";
@Component({
selector: '<userform></userform>',
templateUrl: 'app/users/userform.component.html',
})
export class UserFormComponent implements OnInit{
public myForm: FormGroup;
constructor(private _fb: FormBuilder) {}
ngOnInit() {
this.myForm = this._fb.group({
name: ['', [<any>Validators.required]],
email: ['', Validators.compose([
<any>EmailValidators.emailFormat,
<any>Validators.required
]), EmailValidators.shouldBeUnique], // Async validator
address: this._fb.group({
street: ['', <any>Validators.required],
zipCode: ['']
})
});
}
// save() and other methods here...
}
验证员类:
import {FormControl} from "@angular/forms";
export class EmailValidators {
static shouldBeUnique(control: FormControl) {
console.log("shouldBeUnique called");
return new Promise((resolve, reject) => {
setTimeout(function () {
if (control.value == "m@m.de") {
console.log("shouldBeUnique TRUE");
resolve({shouldBeUnique: true});
} else {
console.log("shouldBeUnique NULL");
resolve(null);
}
}, 1000);
});
}
static emailFormat(control: FormControl) {
var value = <string> control.value;
var regX = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
if (!new RegExp(regX).test(value)) {
console.log("emailFormat: True", value)
return {emailFormat: true};
}
return {emailFormat: null}; // if validation passes return should be null
}
}
HTML:
<div class="form-group">
<label for="email">Email</label>
<input
id="email"
type="text"
class="form-control"
formControlName="email"/>
<div *ngIf="myForm.controls.email.errors.required"
class="alert alert-danger">Email is required {{ myForm.controls.email.errors | json }}</div>
<div *ngIf="myForm.controls.email.errors.emailFormat"
class="alert alert-danger">Email Format should be something like 'yourname@some-domain.com' {{ myForm.controls.email.errors | json }}</div>
<div *ngIf="myForm.controls.email.errors.shouldBeUnique"
class="alert alert-danger">shouldBeUnique {{ myForm.controls.email.errors | json }}</div>
</div>
必需的验证工作正常,自定义emailFormat validator
也能正常工作,divs
正在进入和退出应有的位置,甚至shouldBeUnique validator
如果作为标准验证器实现的话也能正常工作。
但它没有像上面那样实现。甚至不调用验证器类中的静态方法shouldBeUnique
。所以 - 我认为问题出现在组件formGroup
/ formControl
部分的某个地方。请帮忙。
更新
在测试了各种Angular-Versions(目前是CLI / 4.1.3)之后,我在控制台中发现了以下错误:
email: FormControl
asyncValidator: function (control)
arguments: [Exception: TypeError: 'caller' and 'arguments' are restricted function properties and cannot be accessed in this context. at function.remoteFunction (<anonymous>:2:14)]
caller: (...)
更新
...实际上同步验证器出现相同的错误,但这些工作正常。虽然许多教程给人的印象是NG中的异步验证是一项简单的任务,但我也读到了这一点:https://kahlillechelt.com/asynchronous-validation-with-angular-reactive-forms-1a392971c062
混乱。