En esta página

Componentes standalone

15 min lectura TextoCap. 1 — Fundamentos

Standalone components

En Angular moderno (v17+), todos los componentes son standalone por defecto. No necesitas NgModules para organizar tu aplicación.

Anatomia de un componente

Un componente tiene tres partes:

  1. Clase TypeScript — La lógica del componente
  2. Template — La vista HTML
  3. Estilos — CSS encapsulado

Se define con el decorador @Component.

Metadata del componente

El decorador @Component recibe un objeto con propiedades:

  • selector — Nombre de la etiqueta HTML
  • template / templateUrl — HTML del componente
  • styles / styleUrl — CSS del componente
  • imports — Dependencias (otros componentes, directivas, pipes)
  • changeDetection — Estrategia de detección de cambios

Inputs y Outputs

Los componentes se comunican con sus padres mediante:

  • input() — Para recibir datos del padre
  • output() — Para emitir eventos al padre

Estos reemplazan a los decoradores @Input y @Output de versiones anteriores.

// Input requerido
readonly name = input.required<string>();

// Input con valor por defecto
readonly role = input<string>('Estudiante');

// Output (EventEmitter)
readonly selected = output<string>();

Práctica

  1. Crea un componente tarjeta: Crea un componente ProductCard con un input() para el nombre del producto, otro para el precio y un output() que emita cuando se haga click en un boton "Comprar".
  2. Usa el componente desde un padre: Importa ProductCard en otro componente y pasale datos reales. Escucha el evento del output y muestra un mensaje en consola.
  3. Agrega OnPush: Asegurate de que tu componente usa ChangeDetectionStrategy.OnPush y verifica que sigue funcionando correctamente.

En la siguiente leccion aprenderemos sobre Signals para manejar estado.

OnPush
Siempre usa ChangeDetectionStrategy.OnPush. Mejora el rendimiento al evitar verificaciones innecesarias del template.
typescript
import { Component, input, output, ChangeDetectionStrategy } from '@angular/core';

@Component({
  selector: 'app-user-card',
  changeDetection: ChangeDetectionStrategy.OnPush,
  template: `
    <div class="card">
      <h3>{{ name() }}</h3>
      <p>{{ role() }}</p>
      <button (click)="selected.emit(name())">Seleccionar</button>
    </div>
  `,
  styles: `
    .card {
      padding: 1rem;
      border: 1px solid var(--border-color);
      border-radius: 0.75rem;
    }
  `,
})
export class UserCard {
  readonly name = input.required<string>();
  readonly role = input<string>('Estudiante');
  readonly selected = output<string>();
}