我有一个Angular 2应用程序,它使用ReactiveForms
模块来管理使用自定义验证程序的表单。验证器接收FormControl
个对象。我有一些输入字段可以使用相同的自定义验证器,只要我知道FormControl
传递给验证器时字段的名称。
我无法在FormControl
上找到任何公开输入字段名称的方法或公共属性。当然,它很容易看到它的价值。以下显示了我想如何使用它:
public asyncValidator(control: FormControl): {[key: string]: any} {
var theFieldName = control.someMethodOfGettingTheName(); // this is the missing piece
return new Promise(resolve => {
this.myService.getValidation(theFieldName, control.value)
.subscribe(
data => {
console.log('Validation success:', data);
resolve(null);
},
err => {
console.log('Validation failure:', err);
resolve(err._body);
});
});
}
答案 0 :(得分:20)
我们今天可以使用 .parent
属性["_parent"]
(请参阅下文):
export const getControlName = (control: ng.forms.AbstractControl) =>
{
var controlName = null;
var parent = control["_parent"];
// only such parent, which is FormGroup, has a dictionary
// with control-names as a key and a form-control as a value
if (parent instanceof ng.forms.FormGroup)
{
// now we will iterate those keys (i.e. names of controls)
Object.keys(parent.controls).forEach((name) =>
{
// and compare the passed control and
// a child control of a parent - with provided name (we iterate them all)
if (control === parent.controls[name])
{
// both are same: control passed to Validator
// and this child - are the same references
controlName = name;
}
});
}
// we either found a name or simply return null
return controlName;
}
现在我们已准备好调整验证器定义
public asyncValidator(control: FormControl): {[key: string]: any} {
//var theFieldName = control.someMethodOfGettingTheName(); // this is the missing piece
var theFieldName = getControlName(control);
...
.parent
之后,["_parent"]
现在目前(今天,现在),当前版本是:
但请关注此问题:feat(forms): make 'parent' a public property of 'AbstractControl'
如前所述
功能
- 形式:让'parent'成为'AbstractControl'的公共财产(#11855)(445e592)
- ...
我们稍后可以将["_parent"]
更改为.parent
答案 1 :(得分:17)
扩展RadimKöhler的答案。这是编写该功能的一种较短的方式。
getControlName(c: AbstractControl): string | null {
const formGroup = c.parent.controls;
return Object.keys(formGroup).find(name => c === formGroup[name]) || null;
}
答案 2 :(得分:3)
您有两种选择:
借助Attribute
装饰者:
constructor(@Attribute('formControlName') public formControlName) {}
借助Input
装饰者:
@Input() formControlName;
要使用此功能,您的验证当然需要是指令。
答案 3 :(得分:3)
从Angular 4.2.x开始,您可以使用公共父属性访问FormControl
的父FormGroup
(及其控件):
private formControl: FormControl;
//...
Object.keys(this.formControl.parent.controls).forEach((key: string) => {
// ...
});
答案 4 :(得分:1)
您可以在验证器中设置控件名称:
this.form = this.fb.group({
controlName: ['', [Validators.required, (c) => this.validate(c, 'controlName')]]
});
然后:
validate(c: FormControl, name) {
return name === 'controlName' ? {invalid: true} : null;
}
答案 5 :(得分:0)
不完全是您想要的,但您可以像在某些示例中那样动态创建验证器。
像
typeBasedValidator(controlName: string): ValidatorFn {
return(control: AbstractControl): {[key: string]: any} => {
// Your code using controlName to validate
if(controlName == "something") {
doSomething();
} else {
doSomethingElse();
}
}
}
然后在创建表单时使用验证器,传递控件名称 像