twitter bootstrap - formularios - Aplicación de directivas de forma angular2 a elementos de formulario de entrada personalizados
formularios reactivos angular 6 (3)
Quiero crear un componente InputCustom
personalizado y usarlo para crear formularios basados en modelos.
Mi componente personalizado simplemente envuelve un campo de entrada y usa el Bootstrap material design
para look''n''feel.
@Component({
selector:''inputCustom'',
template:`
<div class="form-group label-floating is-empty">
<label class="control-label" for="input">Type here</label>
<input class="form-control" id="input" type="text">
<p class="help-block">Some help text</p>
<span class="material-input"></span>
</div>
`})
class InputCustom{....}
En Angular2 cuando crea una forma impulsada por modelo
<form [ngFormModel]="formRef">
<input type ="email" ngControl="email">
</form>
todos los Controls
presentes en los elementos del formulario se registran en un grupo de ControlGroup
. Mediante el uso de formRef puede rastrear los valores de campo dentro de los controladores.
@Component({...})
class FormController{
formRef: ControlGroup;
constructor(...){
this.form.valueChanges.subscribe(data => console.log(''changes'', data));
}
}
Ahora, quiero que la gente use mi componente como este
<form [ngFormModel]="formRef">
<inputCustom type ="email" ngControl="email">
</form>
P1: ¿Necesito escribir mi propia directiva ngControl
personalizada?
P2: ¿Cómo propagar ngControl
al elemento interno <input>
envuelto por <inputCustom>
?
P3: ¿Cómo debo registrar mi Control
dentro de los formularios ControlGroup
?
Supongo que un ValueAccessor personalizado debería hacer.
Ver
- https://plnkr.co/edit/Bz7wLC5qq7s6Fph1UwpC?p=preview (acceso de valor proporcionado por DI)
providers: [provide(NG_VALUE_ACCESSOR, {useClass: UIDropdownComp, multi: true})]
})
export class UIDropdownComp implements ControlValueAccessor {
- http://plnkr.co/edit/slVMz6Kgv6KlnUNMDe3o?p=preview (ngControl inyectado en el componente y valor de acceso asignado "manualmente")
export class Address implements ControlValueAccessor{
addressForm: ControlGroup;
value:any;
addressForm: ControlGroup;
constructor(@Optional() ngControl: NgControl, elementRef: ElementRef,fb: FormBuilder) {
ngControl.valueAccessor = this;
Ver también https://github.com/angular/angular/issues/2543
El material angular 2 que implementa un elemento de formulario de entrada personalizado es una gran fuente de información para ver cómo implementar ValueAccessor.
Así que simplemente explore el código fuente aquí y eche un vistazo al componente de entrada: https://github.com/angular/material2
Veo dos formas de implementar eso:
Proporcione su control como parámetro de su componente personalizado:
@Component({ selector: ''inputCustom'', template: ` <input [ngFormControl]="control"/> ` export class FormFieldComponent { (...) @Input() control: Control; }
De esta forma, su entrada formará automáticamente parte del formulario definido en el componente principal.
Implemente un componente que cumpla con ngModel . Es un poco más largo de implementar (necesita implementar y registrar un
ControlValueAccessor
dentro de una directiva personalizada) pero de esta manera podrá usar directamentengFormControl
yngModel
directamente en su componente personalizado.<inputCustom type ="email" [ngFormControl]="email">
Consulte esta pregunta para obtener más información: entrada de formulario personalizado angular 2
Creo que este artículo podría interesarte:
- Implementación de formularios Angular2 - Más allá de los conceptos básicos (parte 2) - http://restlet.com/blog/2016/02/17/implementing-angular2-forms-beyond-basics-part-2/