En la primera parte vimos cómo crear la estructura inicial de los proyectos FrontEnd y BackEnd de comparabien.com.pe, en la segunda parte vimos más a detalle la arquitectura de cada proyecto. En esta tercera parte veremos como trabajan los formularios reactivos en Angular implementados por nuestro amigo Jorge Pingo.
Código Fuente
Formularios Reactivos en Angular
Los formularios reactivos proporcionan un enfoque basado en modelos para manejar las entradas cuyos valores cambian todo el tiempo.
En nuestro proyecto veremos como crear y actualizar un formulario básico tal cual lo hace la página comparabien.com.pe.
Importando Reactive Forms Module
Para trabajar con formularios reactivos hay que importar el módulo ReactiveFormsModule:
Depósito a Plazos
El ejemplo que vamos a analizar corresponde a Depósito a Plazos que según el routing es este Componente Web en Angular:
El formulario a manejar es el siguiente, el cual nos permitirá saber que tipo de depósito a plazo queremos: Moneda, Monto, Tiempo y Ubicación.
Formulario 1.0
El FiltroDepositoComponent es la clase TypeScript localizada en el archivo filtro-deposito.component.ts, el cual usará dos componentes, uno para el filtro previo y otro para mostrar los resultados del filtro preliminar. Esto lo podemos apreciar en el HTML:
El filtro-deposito.component.html está conformado de la siguiente manera:
Cómo se aprecia está el componente del filtro (app-compara-deposito) y la segunda parte sería el resultado de aplicar el filtro, que incluye también un filtro similar. Es decir, si en el FORMULARIO 1.0 damos clic al botón Comparar, pasamos a la siguiente ventana:
FORMULARIO 2.0
El que se muestre o no el FORMULARIO 1.0 o FORMULARIO 2.0 dependerá de la siguiente variable boolean llamado estado:
<app-compara-deposito *ngIf="!estado" (emisor) = "cargarData($event)" (ocultar)= "ocultar($event)"></app-compara-deposito>
Pero, también usaremos el siguiente truco para mostrar solo el div si estamos en el componente resultado (FORMULARIO 2.0) y no mostrar el pre filtro (FORMULARIO 1.0).
<div *ngIf="route.children.length != 0">
Some content that should only be shown when the user is at the child component itself.
</div>
<router-outlet></router-outlet>
ComparaDepositoComponent
El primer componente corresponde al FORMULARIO 1.0.
Usaremos una variable form de tipo FormGroup y fb de tipo FormBuilder para crear el formulario.
Si observamos el método ngOnInit revela la creación del formulario, la carga inicial del formulario y la carga de departamentos.
La carga de departamentos usa el departamentoService para traer la data desde nuestro backend.
Si observamos el compara-deposito.component.html este va acorde al formulario creado en el componente, como puedes observar en <form [formGroup]="form"> :
Al hacer clic en "Comparar" se llama al método filtrar().
Este método emite el valor del objeto filtro de tipo ConsultaFiltro, el cual guarda lo que hayamos guardado en el formulario cómo: CODIGO_DEPOSITO, tipoMoneda, valorDeposito, plazo, departamento y banco.
También se emite la opción de ocultar para que pasemos al FORMULARIO 2.0 en la vista padre.
FiltroDepositoComponent
El formulario padre es este y de la misma manera tenemos variables para controlar el formulario.
En el formulario se crea el formulario y se carga con los valores seleccionados en el anterior formulario.
Como se ve ahí se comprueba si el filtro del primer formulario es diferente a null para establecer los valores previamente seleccionados.
La carga de departamentos es similar a lo visto en el primer formulario.
El listado de productos para los filtros seleccionados se da con el método listar() ubicado en el ngOnInit():
El filtro-deposito.component.html muestra el formulario padre, el cual será precargado con los valores del formulario previo:
Este formulario es especial, porque si cambias el algún valor tiene que volverse a mostrar los productos acorde a dichos filtros. Por eso, vamos a observar la llamada al método filtrar() y en el caso del slider se usará en el onChange() el método activateAnimation().
El método se encarga de volver a listar los productos:
this.servicioProducto.listar(filtro).subscribe(data => {
this.servicioProducto.listaCambios.next(data);
});
Este truco que vemos hace uso de un Subject:
De esta manera todos los que están suscritos a dicho Subject recibirán la nueva data y esta se mostrará actualizada donde se utiliza, dándonos una experiencia "reactiva".
Y esto se apreciará en la tabla de productos:
Cómo se aprecia, si ya te interesa un producto puedes ir al detalle:
<button pButton type="button" pTooltip="Ver detalle" tooltipPosition="top" icon="fa fa-info"
class="p-button-raised p-button-success p-button-rounded p-button-sm boton_detalle"
[routerLink]="['detalle-deposito', datos.consultaEntidadProductoId]"></button>
<button pButton type="button" pTooltip="Solicitar" tooltipPosition="top" icon="fa fa-arrow-circle-right"
class="p-button-raised p-button-warning p-button-rounded p-button-sm boton_detalle"
routerLink="/deposito/solicitud"></button>
Y esto es gobernado en el routing:
Gran trabajo de mi amigo
Jorge Pingo implementando toda esta funcionalidad, espero, les haya gustado y lo puedan aplicar en sus proyectos.
Enjoy!
Jose