Te traemos la respuesta a esta dificultad, al menos eso deseamos. Si continuas con dudas coméntalo, que con gusto te responderemos
Solución:
Creo que este enlace responderá a tu pregunta:
- Entrada de formulario personalizado angular 2
Necesitamos implementar dos cosas para lograr eso:
- Un componente que proporciona la lógica de su componente de formulario. No necesita una entrada, ya que la proporcionará el propio ngModel.
- Una costumbre
ControlValueAccessor
que implementará el puente entre este componente yngModel
/ngControl
El enlace anterior te da una muestra completa…
[(ngModel)]="item"
es una abreviatura de [ngModel]="item" (ngModelChange)="item = $event"
Eso significa que si desea agregar una propiedad de enlace bidireccional a su componente, por ejemplo
Todo lo que necesita hacer en su componente es agregar
@Input()
myProp: string;
// Output prop name must be Input prop name + 'Change'
// Use in your component to write an updated value back out to the parent
@Output()
myPropChange = new EventEmitter();
los @Input
manejará las entradas de escritura y para escribir un nuevo valor de vuelta al padre, simplemente llame this.myPropChange.emit("Awesome")
(Puede poner la emisión en un setter para su propiedad si solo quiere asegurarse de que se actualice cada vez que cambie el valor).
Puede leer una explicación más detallada de cómo/por qué funciona aquí.
Si desea utilizar el nombre ngModel
(porque hay directivas adicionales que se unen a elementos con ngModel
), o esto es para un FormControl
elemento en lugar de un componente (también conocido como, para su uso en un ngForm
), entonces tendrás que jugar con el ControlValueAccessor
. Una explicación detallada para hacer su propia FormControl
y por qué funciona se puede leer aquí.
implementé el ngModel
una vez para la entrada en mis componentes compartidos y desde entonces puedo extenderlo de manera muy simple.
Sólo dos líneas de código:
-
providers: [createCustomInputControlValueAccessor(MyInputComponent)]
-
extends InputComponent
mi-entrada.component.ts
import Component, Input from '@angular/core';
import InputComponent, createCustomInputControlValueAccessor from '../../../shared/components/input.component';
@Component(
selector: 'my-input',
templateUrl: './my-input-component.component.html',
styleUrls: ['./my-input-component.scss'],
providers: [createCustomInputControlValueAccessor(MyInputComponent)]
)
export class MyInputComponent extends InputComponent
@Input() model: string;
mi-entrada.componente.html
entrada.componente.ts
import Component, forwardRef, ViewChild, ElementRef, OnInit from '@angular/core';
import NG_VALUE_ACCESSOR, ControlValueAccessor from '@angular/forms';
export function createCustomInputControlValueAccessor(extendedInputComponent: any)
return
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => extendedInputComponent),
multi: true
;
@Component(
template: ''
)
export class InputComponent implements ControlValueAccessor, OnInit
@ViewChild('input') inputRef: ElementRef;
// The internal data model
public innerValue: any = '';
// Placeholders for the callbacks which are later provided
// by the Control Value Accessor
private onChangeCallback: any;
// implements ControlValueAccessor interface
writeValue(value: any)
if (value !== this.innerValue)
this.innerValue = value;
// implements ControlValueAccessor interface
registerOnChange(fn: any)
this.onChangeCallback = fn;
// implements ControlValueAccessor interface - not used, used for touch input
registerOnTouched()
// change events from the textarea
private onChange()
const input = this.inputRef.nativeElement;
// get value from text area
const newValue = input.value;
// update the form
this.onChangeCallback(newValue);
ngOnInit()
const inputElement = this.inputRef.nativeElement;
inputElement.onchange = () => this.onChange();
inputElement.onkeyup = () => this.onChange();