Agregando componentes

Hemos visto que las funcionalidades de una aplicación Angular se crean en componentes (y otras cosas, pero de eso ya hablaremos) y estos se encapsulan en módulos.

En este artículo vamos a ver como crear un componente e implementarlo en nuestra página principal, o en cualquier otra vista del sitio. Además, aprenderemos algo más sobre encapsulación (entendiendo este término en el contexto de Angular, y no por su signifcado estricto en el entorno de POO; aunque la idea final es la misma, existe, cómo es lógico, matices conceptuales).

De momento, vamos a aprender a crear un nuevo componente dentro del módulo con el que estamos trabajando (AppModule), puesto que es el que nos creó el CLI y el único que, de momento, tenemos. Más adelante, ya hablaremos de crear otros módulos, y conectar unos a otros entre sí (cada cosa a su tiempo). Vamos allá.

CREAR UN NUEVO COMPONENTE

Para crear un nuevo componente vamos a usar, cómo no, el comando ng, en este caso con la instrucción generate y especificando que queremos crear un component. Terminaremos el comando con el nombre que queremos darle al componente. Como, por ahora, sólo tenemos un módulo, este componente se creará dentro de dicho módulo. Recuerda el esquema que vimos en este artículo, en el que los componentes se disponen encapsulados en módulos.

Vamos a crear un componente en el que haremos una cabecera, a la que llamaremos header, que se mostrará en todas las vistas de la aplicación.

ATENCIÓN. Fíjate que hablo de «las vistas de la aplicación», en lugar de decir «las páginas del sitio», por ejemplo. Angular 5 es un framework orientado a la creación de lo que se conoce como SPA’s (Single Page Applications, o Aplicaciones de Una Sola Página). Es decir, la aplicación sólo tiene, realmente, una página que es, claro está, el famoso index.html. Las distintas vistas se cargarán siempre en esa página y, aunque cada vista tendrá su propia URL específica, eso es algo que Angular gestionará internamente, pero la página siempre será la misma. No te preocupes demasiado ahora por eso. Cuando veamos enlaces a otras vistas lo entenderás claramente.

Podemos hacerlo tecleando en la terminal la siguiente instrucción (no lo hagas aún; espera un momento):

ng generate component header

o, abreviadamente:

ng g c header

Esto crearía un componente llamado header que será visible en todos los demás componentes que luego creemos en el mismo módulo. Sin embargo, si queremos poder usar esta cabecera en componentes de otros módulos (ya aprenderemos a crearlos), deberemos modificar el comando, así:

ng generate component header --export

o bien:

ng g c header --export

Teclea en tu terminal de VSC esta última instrucción. Observa la respuesta de la terminal:

Nos informa de que se han creado cuatro archivos, y se ha actualizado app.module.ts, es decir, la envoltura del módulo. Los cuatro archivos se han creado dentro de un directorio llamado header (que es el nombre que le hemos dado al componente) que, a su vez, ha quedado alojado en en src/app/. Los cuatro archivos creados son:

  • header.component.html. Contendrá el código HTML del componente. Por ahora, «de fábrica», sólo incluye un párrafo de texto, para que podamos ver si funciona (que, ya te aviso, de momento, va a parecer que no funciona, y en seguida entenderás por qué).
  • header.comoponent.spec.ts. Este archivo es para los test unitarios y de integración, si el componente los necesitara. Como aún no sabemos hacer test, de momento, simplemente, lo «dejamos ahí».
  • header.component.ts. En este componente se alojará toda la lógica TypeScript (que luego será transpilada a JavaScript) del componente. De momento, tiene sólo «lo básico» (enseguida lo comentamos).
  • header.component.css. En este archivo almacenaremos los estilos que queramos usar en el componente. Por defecto está vacío. Una cosa que debemos puntualizar es que los estilos que definamos en este componente no interferirán (no colisionarán) con estilos definidos para otros componentes, aunque les demos los mismos nombres, a menos que queramos que lo hagan. Luego entraremos en detalles.

Además, la envoltura del módulo (app.module.ts) ha sufrido, como nos informa la consola, algunas actualizaciones, para «reconocer» el nuevo componente. Observa el código, tal cómo ha quedado:

En la primer línea resaltada (la 7) vemos que se importa el nuevo componente. En la línea 13 vemos que se ha incluido en la propiedad declarations. Por último, dado que el componente lo creamos con el modificador --export, para poder usarlo luego desde otros módulos, en la línea 21 el nombre del componente se ha incluido en la propiedad exports que, hasta ahora, no existía.

PROBANDO EL COMPONENTE

Vamos a poner en marcha la aplicación. Ya sabes, en la terminal de VSC, teclea npm start y pulsa INTRO. Tal cómo hemos indicado en el package.json, al cabo de unos segundos se abre tu navegador predeterminado y se carga la aplicación.

Cómo ves, el componente header no parece estar funcionando, tal como ya te avisé un poco más arriba que iba a suceder. Enseguida veremos por qué. Parece que debería funcionar, porque está correctamente referenciado en el módulo. Sin embargo, aún nos falta una cosa. Vamos a modificar el archivo app.component.html, quitando todo lo que tiene (el rótulo de la parte superior, la imagen con el logo de Angular, y los tres enlaces que hay). Quitar esto no afecta a nada, es sólo para no tener contenido que nos confunda. En su lugar vamos a poner un titular. El código quedará así:

Observa que hemos respetado la línea final, con las etiquetas <router-outlet></router-outlet>. Esto es porque las necesitaremos más adelante, cuando hablemos de enrutamientos. De momento, «no piden pan», y no nos molestan ni afectan al resultado. Habrá componentes donde, en su momento, deberemos eliminarlas específicamente. Ya lo veremos.

Cuando grabamos los cambios, vemos que la vista en el navegador se cambia con el nuevo contenido.

Ahora abre el archivo header.component.ts del nuevo componente que acabamos de crear. En el decorador ves la propiedad selector. Su contenido está formado por el prefijo de la aplicación, un guión y el nombre del componente, así: a01-header. Bien., pues de manera similar a cómo hacíamos con el AppComponent (a01-root), necesitamos referenciar este selector para poder usar el componente header. Y ¿dónde lo refenciamos? Al contrario que el componente raíz, no lo vamos a referenciar en la página index.html, sino en el HTML del componente que vaya a incluir esta cabecera. Una vez más, editamos el app.component.html, de forma que nos quede así:

Observa que, en la línea resaltada, hemos creado una etiqueta que referencia el selector de header.component.ts, es decir, del nuevo componente. Sin embargo, si miras el navegador, esto parece que sigue sin funcionar, aunque ahora sí que ya debería estar funcionando.

ATENCIÓN. Cuando usamos una aplicación y el servidor ha sido puesto en marcha con --aot (y, cómo hemos dicho, lo usaremos siempre), al añadir un nuevo componente es necesario reiniciar el servidor, es decir, interrumpirlo con Ctrl-C y volver a lanzarlo con npm start.  Esto es una pequeña molestia impuesta por el propio sistema Ahead of Time pero, una vez que lo sabemos, ya no tendremos problemas. Ahora, cuando se carga la aplicación Angular en el navegador, vemos que ya funciona la cabecera, mostrando, en la parte superior, el contenido de header.component.html. Esto sólo es necesario al añadir nuevos componentes, no al modificarlos.

PERSONALIZANDO EL NUEVO COMPONENTE

Vamos a personalizar nuestro nuevo componente header, para que se parezca más a una cabecera de una aplicación. En primer lugar, modificamos el archivo header.component.html, dejándolo así:

Además, vamos a modificar el archivo de estilos del componente header, llamado header.component.css que, de momento está vacío, dejándolo así:

A continuación vamos a modificar el archivo de estilos del AppComponent, llamado app.component.css, así:

Por último, vamos a hacer una pequeña modificación en el archivo de estilos general del sitio. Este se llama styles.css, y de encuentra en el directorio src, al mismo nivel que index.html. Su contenido queda así:

Graba los cambios en todos los ficheros (puedes usar el menú Archivo, opción Guardar todo). Ahora observa como te queda la página en el navegador.

VALE. Artísticamente, nuestra página no es ninguna maravilla. Sin embargo, vemos algo muy relevante, que hemos comentado anteriormente en este artículo, y ahora tenemos ocasión de comprobar. Los estilos de un componente no colisionan con los de otro. Observa los estilos de h1 que tenemos definidos para AppComponent y para HeaderComponent. Ambos son diferentes, y cada h1 muestra sus propios estilos. Esa es la encapsulación de la que hablábamos antes.

LA NOMENCLATURA DE LOS COMPONENTES

Este es un punto que quiero dejar tratado en este artículo. No tiene ninguna ciencia, pero debemos conocerlo, porque, si no, podríamos tener problemas con los nombres de los componentes. Cuando crees un componente debes seguir una serie de reglas, que te voy a comentar ahora:

En primer lugar, el nombre no debe colisionar con ningún nombre de componente de Angular. Si lo hiciera, podrías tener problemas con tu aplicación. Y ¿cómo evitar esto? Bien. Si le das a tus componentes nombres en español, es difícil que se te produzca un problema así, ya que todas las nomenclaturas de Angular están en inglés. Por ejemplo, el componente que hemos creado en este artículo se podría haber llamado cabecera, en lugar de header. Esta es una práctica que no te recomiendo. Va en contra de las buenas prácticas de programación, y es lógico. Si tu código debe revisralo o mantenerlo otro desarrollador que no sea hispano parlante, seguro que en inglés (que es el idioma universal en informática) lo entiende mucho mejor. Otra manera de evitar coliciones de nombres, si tienes dudas, es añadir un prefijo o un sufijo al nombre de tu componente. Por ejemplo, si tenemos dudas acerca de si Angular ya tiene algún componente que se llame header, podemos crearlo con el prefijo que hemos usado para crear el proyecto, cuando empleamos el comando ng new. Así, a nuestro componente le podemos llamar, por ejemplo, a01header o headera01. En este caso, sé que no tengo problemas con el nombre header, pero si tuviera dudas, esta es una buena manera de resover la cuestión.

Los nombres de componentes que tienen dos o más palabras se pueden crear separándolas mediante un guión, un guión bajo o usando la notación camelCase. Por ejemplo, si vas a crear dos cabeceras o más, y a una de ellas quieres llamarla, digamos, Main Header, podrías hacerlo de las siguientes maneras:

ng g c MainHeader

ng g c mainHeader

ng g c Main_header

ng g c main_header

ng g c main-header

Son algunos ejemplos. Seguro que se te ocurre alguna otra combinación. Da igual. Angular 5 tiene esto muy tipificado. Uses la sintaxis que uses, Angular creará, para el componente, un directorio que se llamará main-header, y el componente en sí se llamará MainHeader. La única excepción es si unes las dos palabras sin solución de continuidad, así:

ng g c mainheader

En ese caso, Angular creará un directorio llamado mainheader, y el componente se llamará Mainheader. Obviamente, esto último no es la mejor solución.

CONCLUYENDO

Ahora ya sabemos como crear nuevos componentes en nuestro módulo, y cómo añadirlos al resultado final. En el próximo artículo continuaremos aprendiendo como ampliar las funcionalidades de nuestra aplicación en Angular 5. La aplicación, en su estado actual, te la puedes descargar en este enlace.

ATENCIÓN. Cuando te deje enlaces de descarga, el comprimido que te vas a bajar contiene, únicamente, el directorio src y los archivos de la raíz del sitio. No te incluyo la carpeta node_modules, ni la carpeta e2e porque estas se generan automáticamente al crear cada proyecto Angular. Si es un proyecto nuevo, creálo como hemos aprendido a hacerlo (con el comando ng new) y luego descomprime lo que te dejo en el enlace en la raíz de tu proyecto. Los archivos que extraigas sobrescribirán a los que se han generado por defecto, y la aplicación te funcionará perfectamente.
   

Deja un comentario