Un CRUD atomizado (III). El formulario.

En este artículo vamos a ver como creamos el formulario para los usuarios. Y vamos a hacerlo interesante. El formulario será el mismo para el alta de nuevos usuarios y para la edición de usuarios existentes. Sin embargo, se comportará de forma diferente según el proceso seleccionado.

Esto nos «obliga» a modificar parte del código que ya tenemos, y nos permite ver conocimientos ya aprendidos pero desde un prisma nuevo, lo que nos permitirá afianzar esos conocimientos, y ver nuevas formas de hacer las cosas en Angular. El objetivo es que te sientas seguro, sepas lo que haces, y por donde te mueves.

En concreto, modificaremos el enrutador secundario, y crearemos un formulario versátil. Aprenderemos más sobre formularios cuando hablemos de los reactive forms, pero cada cosa a su tiempo.

En este artículo vamos a implementar las funcionalidades para que se den de alta nuevos miembros. Dejaremos el componente del formulario de tal modo que quedará totalmente opetrativo para nuevas altas. En cambio, para edición, dejearemos algunos detalles prepararados, pero el formulario estará incompleto, y no pondremos aún toda la operativa. Esto es así porque es bastante materia, y vamos a reservar la parte de edición para un artículo posterior, a fin de ir viendo las cosas poco a poco.

EL ENRUTADOR DE MembersModule

Este archivo (members-routing.module.ts) es el primero que vamos a tocar. Su nuevo código nos queda así:

Observa las líneas resaltadas. Date cuenta que hay dos rutas que nos llevan a MemberFormComponent. La primera es accesible a través de form, sin más. Será la que se acceda cuando pulsemos el enlace de grabar un nuevo miembro en la barra de navegación, o el botón correspondiente a la misma función en la vista de la lista de miembros. Ese botón en la lista de miembros es, en realidad, un enlace, así:

<a routerLink="form" class="btn btn-primary">Nuevo</a>

La segunda ruta es accesible a través de form/:id. Nos lleva al mismo componente pero, además, le pasa un parámetro, al que hemos llamado id Observa los dos puntos en la sintaxis. El paso de parámetros por la URL es algo con lo que ya tuvimos un escarceo en este artículo anterior y en este otro artículo. Ahora vamos a consolidar el uso de esta técnica. A esta ruta se llega a través de los botones de edición, en la lista de usuarios que, finalmente, quedan definidos así:

<a routerLink="form/{{ Member.id }}"><span class="btn btn-warning glyphicon glyphicon-pencil">

EL COMPONENTE MemberFormComponent

Al margen del enrutador, cuya adaptación es, como acabas de ver, extremadamente simple, este es el componente clave sobre el que vamos a trabajar. Básicamente, será un formulario que podrá cumplir dos misiones: crear un nuevo miembro o editar uno existente. Por lo tanto, habrá tres puntos en donde deberemos trabajar:

  • La vista del componente (member-form.component.html). El formulario deberá presentarse de diferente forma, según lo que vayamos a hacer (por ejemplo, cambiando el rótulo que se muestra, y algún otro detalle).
  • La lógica del componente (member-form.component.ts). Aquí también hay métodos que cambian según se trate de una edición u un alta nueva. Algunos métodos específicos sólo se usan en uno de los dos procesos.
  • El servicio de conexión (http-connect.service.ts). Este servicio, desde el componente de formularios, es usado para conectar con la API correspondiente.

Cómo ya he comentado, en este artículo vamos a centrarnos en la creación de un nuevo miembro. Aún así, los archivos que hemos mencionado tendrán algunos «toques» que nos revelan que, más adelante, los vamos a ampliar para la edición.

LA LÓGICA DEL COMPONENTE

Como ya sabes, aquí es donde ocurre todo. Te voy a reproducir el código, en su estado actual, con gran profusión de comentarios para que sepas que hace cada método, y porqué está ahí:

Las primeras líneas no aportan nada nuevo. Son las importaciones que ya sabemos que tenemos que hacer. La mayoría son comunes a casi cualquier componente de cualquier módulo.

Dentro de la clase empezamos a ver lo que necesitamos. En primer lugar, en la línea 17 declaramos una variable llamada idRecibido. La declaramos como de tipo string. Si llegamos a este formulario desde edición, en esta variable se almacenará, un poco más adelante, el id del registro que queremos editar. Si llegamos desde la opción de crear una nueva alta, esta variable permanecerá como undefined durante todo el ciclo de vida del componente.

En las líneas de la 18 a la 30 se declaran todas las variables que va a usar el formulario para los datos del miembro que vamos a crear o editar. Aquí se declaran las variables individuales para cada dato, así como una variable para el objeto de la clase Member. También se declara un objeto de la clase FormData, para empaquetarlo todo antes de mandarlo al servicio que lo pasará a la API. Quizá te llamen la atención las variables doiGrabar y nombreGrabar que hemos declarado en las líneas 22 y 23. Cuando vayamos a grabar un registro, una de las cosas que tenemos que asegurarnos es que no se hayan rellenado estos campos con espacios en blanco. La aplicación no permite dejarlos vacíos, pero algún usuario «patoso» podría rellenarlos con espacios en blanco. Sin embargo, no podemos aplicar el método trim() directamente a las variables doi y nombre, porque estas enlazan con el formulario mediante [(ngModel)], lo que daría lugar a un error. Por lo tanto, una vez que se pide enviar el formulario, los valores de doi y nombre pasan a doiGrabar y nombreGrabar, sobre las que sí podemos aplicar el método trim(). Estas serán las que, finalmente, se empaqueten en el objeto.

Las variables booleanas que se declaran entre las líneas 34 y 41 se emplean para mostrar u ocultar mensajes al usuario, en el formulario, según se haya producido algún error en el proceso, o si todo ha ido bien y el nuevo usuario se ha grabado correctamente.

En la firma del constructor declaramos dos objetos (que, por estár declarados en la firma ya sabemos que estarán disponibles para toda la clase, como si se hubieran declarado previamente). Uno es de la clase HttpConnectService, y lo usaremos para conectar con el servicio que envía los datos a las API’s. El otro es de la clase ActivatedRoute. ActivatedRoute es, realmente, otro servicio, solo que este no le hemos creado nosotros. Es propio de Angular y se usa, entre otras cosas, para identificar los parámetros pasados por la ruta, si los hay. No nos haría falta si este componente sólo se fuera a usar para nuevas altas pero, como nos hará falta para identificar el id de un usuario cuando hagamos la parte de edición, pues ya lo dejamos importado. Dentro del constructor, en la línea 51, usamos el objeto ruta, de la clase ActivatedRoute, para identificar el parámetro id, si lo hay. Lo identifica a partir de la captura de la URL (snapshot). Esta es la captura, digamos, en una «foto» de la ruta tal como se ha llamado. Es decir. Si, por alguna razón, en la URL «aparece» algo nuevo, snapshot no lo detectará. Esto se podría dar en determinados casos de los que ya hablaremos. Por ahora, nos basta saber que el snapshot es justo lo que necesitamos. Y dentro de este, la matriz params contiene los parámetros que hay en la ruta. Como buscamos el parámetro id, si estamos haciendo la llamada para un alta nueva, este no existe, por lo que obtendremos undefined. Lo que leamos de este parámetro pasa a idRecibido. Si hay algo que no sea undefined (una edición), se ejecutará el método readActualData(). Como es para la edición, ese método está declarado, pero aún no está construido. En caso de alta nueva, se establece una fecha por defecto para la fecha de inscripción, y se muestra, como avatar, el icono sin_avatar.jpg.

El resto de los métodos ya nos son familiares, del anterior CRUD que hicimos, por lo que no vamos a detenernos en ellos más allá de los comentarios del código. Lo que quizá pueda llamarte la atención es la forma de resetear el formulario en la línea 197:

$('#MemberDataForm')[0].reset();

Observa que referenciamos el formulariuo a través de jQuery. Sin embargo, ves el índice [0], que no cabría esperar en una instrucción como esta. Eso es porque Angular «envuelve» el formulario en una capa adicional. Con el uso de ese índice, lo «sacamos» de esa envoltura, para poder aplicarle el método reset().

CONCLUYENDO

En este artículo hemos aprendido a organizar todo el código, y dejarlo medio preparado para una futura ampliación y, lo que es más importante, hemos afianzado conocimientos que vamos a necesitar tener muy presentes en cualquier proyecto. La aplicación, en su estado actual, puedes descargarla en este enlace. En el próximo artículo seguiremos aprendiendo cosas nuevas con este CRUD.

   

Deja un comentario