Componentes

<< Crear un proyecto Plantillas >>

En Angular, una aplicación se divide en componentes. Un componente representa una página, o una porción de una página, de nuestra aplicación web. Engloba el HTML de dicha porción (plantilla), el CSS específico que solo afecta a ese HTML, y una clase que gestiona dicha plantilla.

Partes de un componente

Cuando creamos el proyecto, se generó el componente AppComponent (src/app/app.component.ts). El código debería ser similar al siguiente:

import { Component } from '@angular/core';
import { RouterOutlet } from '@angular/router';

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [RouterOutlet],
  templateUrl: './app.component.html',
  styleUrl: './app.component.css'
})
export class AppComponent {
  title = 'angular-products';
}

Un componente es una clase que tiene un decorador @Component y unos parámetros de configuración dentro del mismo:

  • selector → Este es el nombre de etiqueta que se usará en la vista (HTML) donde se insertará la plantilla de este componente. Dado que HTML no distingue entre mayúsculas y minúsculas, se utiliza '-' para separar palabras. Observa src/index.html y verás la etiqueta <app-root>. Cuando Angular se carga, reemplazará el contenido de esa etiqueta con la plantilla del componente AppComponent. Por defecto, cada componente se crea con un selector prefijado con "app". Puedes cambiar este prefijo (o eliminarlo) al crear el proyecto. Ejemplo: ng new my-project --prefix mp. Pero también puedes hacerlo más tarde en angular.json (busca el atributo "prefix").
  • standalone → Si se establece a true , este componente no depende de ningún módulo y puede ser importado y utilizado en cualquier parte de nuestra aplicación. A partir de la versión 19 de Angular, este será el valor por defecto si establecemos esta propiedad.
  • imports → Array de componentes (standalone), directivas o módulos que el componente importará para poder usar en su plantilla.
  • templateUrl → Este es el archivo donde se encuentra la vista controlada por este componente. Contendrá código HTML (plantilla) que se insertará dentro del selector del componente cuando se cargue.
  • styleUrls → Angular te permite asignar uno o más archivos CSS al componente. Estos estilos se aplicarán solo a la plantilla del componente. Esto nos permite crear componentes modulares y reutilizables con su propio estilo. Nota: Los estilos generales para toda la aplicación pueden incluirse en el archivo src/styles.css

Además, la clase ha sido creada con una propiedad llamada "title". En la plantilla (que es un ejemplo que borraremos) busca este código:

<span>{{ title }} app is running!</span>

Esto se llama interpolación, como veremos en la siguiente sección. Cuando el componente se carga, cambiará "{{title}}" por el texto "angular-products". Cambia la propiedad "title" en la clase del componente para observar como cambia su valor en el HTML generado.

Plantilla en línea

En lugar de utilizar un template externo (archivo HTML), podríamos definir el template en el decorador del componente como una cadena utilizando "template" en lugar de "templateUrl". Lo mismo se puede aplicar al CSS si usamos "styles" en lugar de "styleUrls".

@Component({
  selector: 'app-root',
  template: `
    <h1>
      {{title}}
    </h1>`,
  styles: [`
    h1 {
       color: green;
    }
  `]
})
export class AppComponent {
  title = 'angular-products';
}

Esto es práctico para componentes pequeños o ejemplos donde queramos visualizar todo en un solo archivo. Sin embargo, en este curso no trabajaremos así, prefiriendo el enfoque por defecto donde la plantilla y los estilos están en archivos separados.

Prefijo de los selectores

Por defecto, todos los selectores de componentes (y directivas) comienzan con el prefijo 'app'. Esto se puede cambiar al crear un proyecto con la opción -p, o --prefix. Si vamos a crear una librería de componentes reutilizables, es mejor elegir un prefijo apropiado relacionado con el nombre de nuestra librería. Si los componentes son solo para la aplicación que estamos construyendo, podríamos eliminar el prefijo.

Para nuestra aplicación de ejemplo, en el archivo angular.json vamos a establecer un prefijo vacío para los selectores de los componentes.

{
  "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
  "version": 1,
  "newProjectRoot": "projects",
  "projects": {
    "angular-products": {
      // Resto de propiedades
      "prefix": "",
      // Resto de propiedades
    }
  }
}

Vamos a editar también el archivo .eslintrc.json (si hemos instalado ESLint) y quitar el prefijo app ahí también. Por defecto obliga que los componentes y directivas tengan este prefijo en el selector.

// @ts-check
const eslint = require("@eslint/js");
const tseslint = require("typescript-eslint");
const angular = require("angular-eslint");

module.exports = tseslint.config(
  {
    files: ["**/*.ts"],
    // Resto de configuración
    rules: {
      "@angular-eslint/directive-selector": [
        "error",
        {
          type: "attribute",
          prefix: "",
          style: "camelCase",
        },
      ],
      "@angular-eslint/component-selector": [
        "error",
        {
          type: "element",
          prefix: "",
          style: "kebab-case",
        },
      ],
    },
  },
  {
    files: ["**/*.html"],
    // Resto de configuración
  }
);

Añadir estilo global: Bootstrap

Para añadir algo de estilo a la aplicación, vamos a instalar Bootstrap e incluir el CSS de dicha librería en nuestro proyecto de forma global.

npm i bootstrap

Ahora tenemos 2 opciones para importar el CSS de Boostrap en nuestra aplicacion. La primera sería desde el archivo src/styles.css, usando la instrucción @import de CSS:

/* You can add global styles to this file, and also import other style files */
@import "bootstrap/dist/css/bootstrap.css";

Otra forma sería incluyendo el archivo CSS en el array styles dentro del archivo de configuración angular.json:

{
  "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
  "version": 1,
  "newProjectRoot": "projects",
  "projects": {
    "angular-products": {
      //...
      "architect": {
        "build": {
          "builder": "@angular-devkit/build-angular:application",
          "options": {
            //...
            "styles": [
              "node_modules/bootstrap/dist/css/bootstrap.css",
              "src/styles.css"
            ],
            "scripts": []
          },
          //...
        },
        //...
      }
    }
  }
}

Creando un nuevo componente

Para crear un nuevo componente ejecutamos ng generate component nombre-componente, o simplemente ng g c nombre-componente. Algunas opciones que podemos añadir son:

  • --inline-template → En lugar de crear un archivo HTML separado, insertará la plantilla en la cadena template del componente.
  • --inline-style → Igual que la anterior pero para el archivo CSS.
  • --flat → No crea un directorio para el componente, simplemente los archivos. Esta opción tiene más sentido en combinación con las opciones --inline-template y --inline-style, ya que solo nos creará un archivo.

Vamos a crear un componente donde mostraremos un listado de productos.

ng g c products-page

Como podremos observar, dentro del directorio app, se habrá creado la carpeta products-page con los archivos del nuevo componente. La clase del componente (products-page.component.ts) tendrá un aspecto similar a este:

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

@Component({
  selector: 'products-page',
  standalone: true,
  imports: [],
  templateUrl: './products-page.component.html',
  styleUrl: './products-page.component.css'
})
export class ProductsPageComponent { }

En el archivo de la plantilla (products-page.component.html), vamos a añadir el esqueleto de una tabla donde añadiremos los productos que vamos a mostrar.

<div class="card">
  <div class="card-header bg-primary text-white">
    Mi lista de productos
  </div>
  <div class="card-block">
    <div class="table-responsive">
      <table class="table table-striped m-0">
        <thead>
          <tr>
            <th>Producto</th>
            <th>Precio</th>
            <th>Disponible</th>
          </tr>
        </thead>
        <tbody>
          <!-- Por ahora vacío. Aquí van los productos -->
        </tbody>
      </table>
    </div>
  </div>
</div>

En la siguiente sección, "Plantillas", veremos como añadir este componente a la plantilla del componente App para visualizarlo en el documento.

<< Crear un proyecto Plantillas >>