[英]How to get name of input field from Angular2 FormControl object?
I have an Angular 2 application that uses the ReactiveForms
module to manage a form that uses a custom validator.我有一个 Angular 2 应用程序,它使用ReactiveForms
模块来管理使用自定义验证器的表单。 The validator receives a FormControl
object.验证器接收一个FormControl
对象。 I have a few input fields that could use the same custom validator if only I knew the name of the field when the FormControl
was passed to the validator.我有几个输入字段可以使用相同的自定义验证器,前提是我在将FormControl
传递给验证器时知道字段的名称。
I can't find any method or public property on FormControl
that exposes the input field's name.我在FormControl
上找不到任何公开输入字段名称的方法或公共属性。 It's simple enough to see its value, of course.当然,很简单就能看出它的价值。 The following shows how I would like to use it:下面显示了我想如何使用它:
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);
});
});
}
To expand on Radim Köhler answer.扩展 Radim Köhler 的答案。 here is a shorter way of writing that function.这是编写该函数的较短方法。
getControlName(c: AbstractControl): string | null {
const formGroup = c.parent.controls;
return Object.keys(formGroup).find(name => c === formGroup[name]) || null;
}
We can use .parent
property, well today ["_parent"]
(see more below) :我们可以使用.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;
}
and now we are ready to adjust our validator definition现在我们准备调整我们的验证器定义
public asyncValidator(control: FormControl): {[key: string]: any} {
//var theFieldName = control.someMethodOfGettingTheName(); // this is the missing piece
var theFieldName = getControlName(control);
...
.parent
later, ["_parent"]
now .parent
以后, ["_parent"]
现在At the moment (today, now) , current release is :目前(今天,现在) ,当前版本是:
2.1.2 (2016-10-27) 2.1.2 (2016-10-27)
But following this issue: feat(forms): make 'parent' a public property of 'AbstractControl'但是在这个问题之后: feat(forms): make 'parent' a public property of 'AbstractControl'
And as already stated here正如这里已经说明的那样
2.2.0-beta.0 (2016-10-20) 2.2.0-beta.0 (2016-10-20)
Features特点
- forms: make 'parent' a public property of 'AbstractControl' (#11855) (445e592)表单:使 'parent' 成为 'AbstractControl' 的公共属性 (#11855) (445e592)
- ... ...
we could later change the ["_parent"]
into .parent
我们可以稍后将["_parent"]
更改为.parent
As of Angular 4.2.x, you can access a FormControl
's parent FormGroup
(and its controls) using the public parent property:从 Angular 4.2.x 开始,您可以使用公共父属性访问FormControl
的父FormGroup
(及其控件):
private formControl: FormControl;
//...
Object.keys(this.formControl.parent.controls).forEach((key: string) => {
// ...
});
You have two options:您有两个选择:
With the help of the Attribute
decorator:在Attribute
装饰器的帮助下:
constructor(@Attribute('formControlName') public formControlName) {}
With the help of the Input
decorator:在Input
装饰器的帮助下:
@Input() formControlName;
To use this your validation needs to be a directive of course.要使用它,您的验证当然需要是一个指令。
You can set control name in validators:您可以在验证器中设置控件名称:
this.form = this.fb.group({
controlName: ['',
[
Validators.required,
(c) => this.validate(c, 'controlName')
]
]
});
And then:然后:
validate(c: FormControl, name) {
return name === 'controlName' ? {invalid: true} : null;
}
Not exactly what you want but you could dynamically create the validator like in some examples.不完全是您想要的,但您可以像某些示例中那样动态创建验证器。
like喜欢
typeBasedValidator(controlName: string): ValidatorFn {
return(control: AbstractControl): {[key: string]: any} => {
// Your code using controlName to validate
if(controlName == "something") {
doSomething();
} else {
doSomethingElse();
}
}
}
Then use the validator when creating the form, passing the control name like然后在创建表单时使用验证器,传递控件名称,如
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.