reactivos - validar formulario angular 5
Obtenga acceso a FormControl desde el componente de formulario personalizado en Angular (4)
Tengo un componente de control de formulario personalizado en mi aplicación Angular, que implementa la interfaz
ControlValueAccessor
.
Sin embargo, quiero acceder a la instancia de
FormControl
, asociada con mi componente.
Estoy usando formularios reactivos con
FormBuilder
y proporciono control de formularios usando el atributo
formControlName
.
Entonces, ¿cómo
FormControl
instancia de
FormControl
desde mi componente de formulario personalizado?
Como @Ritesh ya ha escrito en el comentario, puede pasar el control del formulario como un enlace de entrada:
<my-custom-form-component [control]="myForm.get(''myField'')" formControlName="myField">
</my-custom-form-component>
Y luego puede obtener una instancia de control de formulario dentro de su componente de formulario personalizado como este:
@Input() control: FormControl;
Esta solución nació de la discusión en el repositorio Angular. Por favor, asegúrese de leerlo o incluso mejor para participar si está interesado en este problema.
Estudié el código de la directiva
FormControlName
y me inspiró a escribir la siguiente solución:
@Component({
selector: ''my-custom-form-component'',
templateUrl: ''./custom-form-component.html'',
providers: [{
provide: NG_VALUE_ACCESSOR,
useExisting: CustomFormComponent,
multi: true
}]
})
export class CustomFormComponent implements ControlValueAccessor, OnInit {
@Input() formControlName: string;
private control: AbstractControl;
constructor (
@Optional() @Host() @SkipSelf()
private controlContainer: ControlContainer
) {
}
ngOnInit () {
if (this.controlContainer) {
if (this.formControlName) {
this.control = this.controlContainer.control.get(this.formControlName);
} else {
console.warn(''Missing FormControlName directive from host element of the component'');
}
} else {
console.warn(''Can/'t find parent FormGroup directive'');
}
}
}
Estoy inyectando el
FormGroup
primario al componente y luego
FormControl
el
FormControl
específico de él usando el nombre de control obtenido a través del enlace
formControlName
.
Sin embargo, tenga en cuenta que esta solución está diseñada específicamente para el caso de uso donde se
FormControlName
directiva
FormControlName
en el elemento host.
No funcionará en otros casos.
Para esto necesitará agregar alguna lógica adicional.
Si cree que Angular debería abordar esto, asegúrese de visitar
la discusión
.
Para cualquiera que venga aquí en 2019, con Angular 6/7 +, la solución que no arroja una advertencia de desaprobación es la que se describe en esta respuesta:
https://.com/a/56061527/134120
Para más detalles, mire esta presentación , como se describió anteriormente.
Usar
formControlName
como parámetro de entrada no funciona cuando se vincula a través de la directiva
[formControl]
.
Aquí hay una solución que funciona en ambos sentidos sin ningún parámetro de entrada.
export class MyComponent implements AfterViewInit {
private control: FormControl;
constructor(
private injector: Injector,
) { }
// The form control is only set after initialization
ngAfterViewInit(): void {
const ngControl: NgControl = this.injector.get(NgControl, null);
if (ngControl) {
this.control = ngControl.control as FormControl;
} else {
// Component is missing form control binding
}
}
}