angular - Hur får man namnet på ett inmatningsfält från ett Angular2 FormControl-objekt?
Jag har en Angular 2-applikation som använder ReactiveForms-modulen för att hantera ett formulär som använder en anpassad validator. Validatorn tar emot ett FormControl-objekt. Jag har några inmatningsfält som skulle kunna använda samma anpassade validator om jag bara visste namnet på fältet när FormControl skickades till validatorn.
Jag kan inte hitta någon metod eller publik egenskap på FormControl som exponerar inmatningsfältets namn. Det är förstås tillräckligt enkelt att se dess värde. Följande visar hur jag skulle vilja använda det:
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);
});
});
}
Svar #1
För att utveckla Radim Köhlers svar. här är ett kortare sätt att skriva den funktionen.
getControlName(c: AbstractControl): string | null {
const formGroup = c.parent.controls;
return Object.keys(formGroup).find(name => c === formGroup[name]) || null;
}
Svar #2
Vi kan använda .parent-egenskapen, idag ["_parent"] (se mer nedan):
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;
}
och nu är vi redo att justera vår validator-definition
public asyncValidator(control: FormControl): {[key: string]: any} {
//var theFieldName = control.someMethodOfGettingTheName(); // this is the missing piece
var theFieldName = getControlName(control);
...
.parent senare, ["_parent"] nu
För tillfället (idag, nu), aktuell version är :
2.1.2 (2016-10-27)
Men efter denna fråga: feat(forms): gör 'parent' till en offentlig egenskap hos 'AbstractControl'
Och som redan nämnts här
2.2.0-beta.0 (2016-10-20)
Funktioner
- forms: gör 'parent' till en offentlig egenskap av 'AbstractControl' (#11855) (445e592)
- ...
vi skulle senare kunna ändra ["_parent"] till .parent
Svar #3
Du kan ange kontrollnamn i validatorer:
this.form = this.fb.group({
controlName: ['',
[
Validators.required,
(c) => this.validate(c, 'controlName')
]
]
});
Och sedan:
validate(c: FormControl, name) {
return name === 'controlName' ? {invalid: true} : null;
}
