¿Qué es un componente?

Bien, un concepto importante que tienes que aprender sobre Angular es el concepto de componente. Angular se basa sobre todo en componentes, así que lo primero y fundamental es ver este concepto.

Un componente es una parte de la web que tiene vista, estilos y lógica. Las etiquetas HTML en cierto modo no dejan de ser componentes, por ejemplo, la etiqueta <input> es un componente porque, de forma predeterminada, se pinta con unos estilos y con la lógica necesaria para que el usuario pueda hacer clic y escribir en ellos.

En otras palabras, con los componentes web puedes crear tus propias etiquetas HTML que podrás reusar en toda la página web. En Angular y en otros frameworks los componentes suelen recibir una propiedad o varias que sirven de entrada para la configuración de ese componente (por ejemplo a los inputs le puedes pasar el tipo: text, password, email...).

Los componentes de Angular van más allá y pueden incluso recibir objetos javascript completos y arrays para su configuración. Por ejemplo puedes crear un componente para pintar una lista de usuarios. Este componente recibirá como entrada un array de usuarios a pintar. De esta forma consigues en puedas reutilizar esta lista en otra parte de la web, por lo que es fundamental que los hagas lo más genéricos posibles para que se puedan reusar.

En Angular los componentes tienen un archivo por cada parte del componente, es decir, se suele crear un archivo .html para la vista, otro .ts (typescript) para la lógica del componente y otro .css o .scss para los estilos del componente.

Dentro de la lógica del componente, en archivo .ts, es el lugar en el que se define el funcionamiento de ese componente. Aquí se definen las variables, se crean los métodos y se recogen y preparan los datos para pasarlos a la vista.

Dentro de los componentes también se pueden llamar o hacer uso de otros componentes, por lo que al final se suelen tener estructuras con forma de árbol.

Por ejemplo una estructura de componentes con componentes padres e hijos puede ser la siguiente:

Un componente que tiene dos componentes hijos y a su vez, su hijo tiene otros dos hijos

Creando componentes en Angular

Vamos ahora con la creación de componentes en Angular. Manos a la obra.

Antes de nada te recomiendo que ya tengas creado un proyecto de Angular. Si no sabes cómo instalar Angular y cómo crear un proyecto te recomiendo que mires el artículo de Introducción a Angular.

Existen dos maneras de hacerlo: la método automático y el manual.

Método automático

Si estamos usando Angular CLI, en nuestro proyecto, existe un comando muy útil para generar la estructura básica de un componente.

Por ejemplo, imaginemos que queremos crear un componente que sirva para crear el menú principal de una web y que lo queremos llamar navbar por el momento. Tan solo tienes que ejecutar en la terminal:

ng generate component navbar

La última palabra es el nombre del componente. Si es un componente de varias palabras yo recomiendo que le des un nombre en kebab-case, es decir, separada cada palabra por un guión, por ejemplo: user-list.

Si navegamos ahora a la carpeta app del proyecto veremos que Angular CLI ha creado por nosotros una carpeta llamada navbar. Dentro de la carpeta navbar se ha creado un archivo css, un archivo html y un archivo .ts (controlador) junto con un .spec.ts (este archivo es para los tests, no te preocupes de momento).

Otro detalle a tener en cuenta es que Angular ha importado por nosotros el nuevo componente en el archivo app.module.ts. El archivo app.module.ts sirve para declarar los componentes a nivel global para poder reutilizarlos más tarde.

Método manual

Si no estás usando Angular CLI, o no quieres usarlo, tendrás que crear los archivos que genera el comando a mano.

Lo único que tienes que hacer es generar una nueva carpeta dentro de la carpeta app con el nombre del componente que quieras. Dentro de la carpeta creas un archivo que se llame nombre-componente.component.ts, por ejemplo navbar.component.ts.

Dentro de ese componente escribes esta estructura:

// app/navbar/navbar.component.ts

import { Component } from "@angular/core";

@Component({
  selector: "app-navbar",
  templateUrl: "./navbar.component.html",
  styleUrls: ["./navbar.component.css"],
})
export class NavbarComponent {}

Para que no salte error también tendrás que crear el archivo nombre-componente.component.html y nombre-componente.component.css, por el momento vacíos. Para el ejemplo del componente de navbar lo que hago es crear: navbar.component.html y navbar.component.css.

Por último tendrás que importar el componente dentro del archivo app.module.ts que como hemos dicho se encarga de definir los componentes que puedes usar. Para nuestro ejemplo:

// app.module.ts

import { BrowserModule } from "@angular/platform-browser";
import { NgModule } from "@angular/core";

import { AppComponent } from "./app.component";
import { NavbarComponent } from "./navbar/navbar.component";

@NgModule({
  declarations: [AppComponent, NavbarComponent],
  imports: [BrowserModule],
  providers: [],
  bootstrap: [AppComponent],
})
export class AppModule {}

Estructura básica de los componentes

Ahora que ya tenemos el componente creado vamos a echar un vistazo a lo que tiene de forma básica.

Como hemos dicho antes, un componente en Angular debería tener 3 archivos, uno .html, otro .ts y otro .css o .scss.

Los archivos html y css no tienen mucho misterio de moment y los podemos tener vacíos. Dentro del .html puedes escribir código HTML como haces normalmente (más adelante veremos cómo pintar variables del componente, condicionales y bucles) y dentro del .css o .scss se escriben los estilos que va a tener ese componente.

OJO a esto porque es importante. Los estilos CSS que apliques en ese archivo solo afectarán a cómo se vea ese componente y no afectará a otros componentes. Esto permite que los estilos no se peguen entre sí por lo que no pasa nada que haya dos componentes con la misma clase CSS.

Veamos ahora el archivo .ts también llamado controlador que es el que define la lógica del componente. La estructura básica ya la has visto, pero por si acaso es esta:

// app/navbar/navbar.component.ts

import { Component } from "@angular/core";

@Component({
  selector: "app-navbar",
  templateUrl: "./navbar.component.html",
  styleUrls: ["./navbar.component.css"],
})
export class NavbarComponent {
  constructor() {}
}

Lo primero que se hace es importar Component de @angular/core. Esto sirve para poder invocar justo debajo @Component, una especie de método que recibe un objeto con la configuración del componente. Dentro de esa configuración hay tres propiedades:

  • selector: El selector es el nombre que va a tener la etiqueta HTML que sirve para poder usar este componente, para este ejemplo del navbar será <app-navbar></app-navbar>, es decir, desde el HTML de cualquier otro componente poniendo esa etiqueta se pintará el navbar. A

    Angular tiene una convención de nombre para el selector, kebab-case (el nombre de los selectores tiene que ser una palabra seguida de un guión y otra palabra: app-ejemplo).

  • templateUrl: La ruta al fichero .html de ese componente para crear la vista.

  • styleUrl: La ruta al fichero .html de ese componente para crear la vista.

Lo normal es que estás rutas empiecen por ./ (carpeta actual) ya que normalmente los ficheros html y css se encuentran en la misma carpeta que el fichero .ts.

Por último hacemos export class con el nombre del componente (sin guiones aquí). Dentro del export se crea el método constructor (vacío por el momento).

¡OJO!. El nombre que usas cuando exportas el componente (NavbarComponent en el ejemplo de arriba) es el que luego tienes que poner entr llaves para importar el componente dentro del app.module, en este caso:

import { NavbarComponent } from "./navbar/navbar.component";

Cómo usar los componentes dentro de otros

Si ya has creado el componente (puedes añadir alguna etiqueta HTML en el .html) y si ya lo tienes importado correctamente en el app.module.ts, puedes probar que el componente funciona correctamente simplemente creando etiqueta dentro del archivo app.component.html.

En mi caso he borrado todo el contenido del archivo y he puesto:

<!-- app.component.html -->
<div>
  <app-navbar></app-navbar>
</div>

Si el archivo .html del componente que has creado tiene algún contenido podrás verlo si te abres la página en el navegador (localhost:4200).

Conclusiones

Lo que yo recomiendo es hacer componentes genéricos y abstraerse para permitir mayor reutilización.

Mira la imagen de abajo, se crea un componente para la cabecera, otro para la lista de items y otro por cada item. Esto permite que puedas reutilizar cada uno de estos componentes en otros sitios.

Una página que tiene un componente de cabecera, otro para mostrar todos los elementos, y un componente por cada elemento de la lista

Te recomiendo que ahora que sabes crear componentes eches un ojo al método de ngOnInit de Angular y a la Inyección de dependencias en Angular, partes fundamentales de los componentes.