Jese Leos

Ing en Sistemas Computacionales

Componentes (creación, ciclo de vida, comunicación)

#angular , #programacion , #blog

Angular 20 continúa la evolución del framework, ofreciendo mejoras en el manejo de componentes, ciclo de vida y estrategias de comunicación. En esta guía avanzada, exploramos estos conceptos en profundidad, y te comparto consejos y trucos para dominar componentes en tus aplicaciones modernas.

1 . Creación de Componentes en Angular 20

Estructura y Decoradores

En Angular, los componentes se crean usando el decorador @Component. En la versión 20, puedes aprovechar nuevas opciones de standalone components, control de imports y mejoras en el tipado.

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

@Component({
 selector: 'app-advanced-example',
 templateUrl: './advanced-example.component.html',
 styleUrls: ['./advanced-example.component.scss'],
 standalone: true, // Angular 20 Standalone Components
 imports: [],
})

export class AdvancedExampleComponent {
 // Propiedades y lógica aquí
}

Consejos

  • Standalone Components: Usa standalone: true para evitar declarar componentes en módulos, facilitando lazy loading y reutilización.
  • Type-Safe Inputs/Outputs: Aprovecha el tipado estricto de Angular 20 para Inputs/Outputs.
  • SCAM Pattern: Considera el patrón Single Component Angular Module (SCAM), aunque con standalone la necesidad es menor.

1 . Creación de Componentes en Angular 20

Angular provee hooks para controlar el ciclo de vida de los componentes, permitiendo ejecutar lógica en momentos clave.

Hook Descripción
ngOnChanges Cambios en los inputs
ngOnInit Inicialización del componente
ngDoCheck Detección personalizada de cambios
ngAfterContentInit Proyección de contenido
ngAfterContentChecked Después de verificar el contenido
ngAfterViewInit Inicialización de vistas hijas
ngAfterViewChecked Después de comprobar vistas hijas
ngOnDestroy Limpieza antes de destruir el componente

Ejemplo de Uso

import { 
Component, Input, OnInit, OnDestroy, AfterViewInit 
} from '@angular/core';

@Component({
selector: 'app-lifecycle-demo',
template: '<p>{{data}}</p>',
standalone: true
})
export class LifecycleDemoComponent implements OnInit, OnDestroy, AfterViewInit {
@Input() data: string = '';

ngOnInit() {
 // Ideal para inicializar data que depende de los Inputs
}

ngAfterViewInit() {
 // Manipulación directa de la vista (evitar manipulación DOM directa)
}

ngOnDestroy() {
 // Limpieza (ej: unsusbscribe a observables)
}
}

Consejos

  • Evita Lógica Compleja en Hooks: Limita la lógica en hooks a lo necesario, especialmente en ngOnChanges y ngDoCheck.
  • Observables y Limpieza: Usa el operador takeUntil o la función DestroyRef (Angular 20) para gestionar suscripciones.
  • ngOnInit vs Constructor: Usa el constructor solo para inyectar dependencias, no para inicialización lógica.

3. Comunicación Entre Componentes

Angular ofrece múltiples formas para la comunicación entre componentes. Elige la estrategia según la relación entre los componentes.

A. Inputs y Outputs

La forma más directa de comunicación padre-hijo.

// Hijo
@Input() value!: string;
@Output() changed = new EventEmitter<string>();

B. ViewChild y ContentChild

Permiten acceder a hijos directos en la plantilla o contenido proyectado.

@ViewChild(ChildComponent) childComp!: ChildComponent;

B. ViewChild y ContentChild

Permiten acceder a hijos directos en la plantilla o contenido proyectado.

@ViewChild(ChildComponent) childComp!: ChildComponent;

C. Servicios Compartidos

Para comunicación entre hermanos o componentes distantes, usa servicios con RxJS Subjects o Signals.

 @Injectable({ providedIn: 'root' })
   export class DataService {
     private data$ = new BehaviorSubject<string>('init');
     dataChanged$ = this.data$.asObservable();

     updateData(value: string) {
       this.data$.next(value);
     }
 }

D. Signals (Angular 16+)

Signals es la nueva forma reactiva recomendada para compartir y reaccionar a cambios de estado.

import { signal, computed } from '@angular/core';

export class CounterService {
 count = signal(0);
 doubled = computed(() => this.count() * 2);

 increment() {
   this.count.update(v => v + 1);
 }
}

E. Router y State Management

Para casos complejos, utiliza el Angular Router para pasar datos o integra herramientas como NgRx, Akita, o NGXS.

Trucos y Mejores Prácticas

  • Emite Objetos, No Primitivos: Al usar Outputs, emite objetos para facilitar la extensión.
  • Unsubscribe Siempre: Usa takeUntil, DestroyRef o decoradores automáticos para evitar memory leaks.
  • Signals para Estado Local: Prefiere signals para el estado interno reactivo, sobre todo en componentes standalone.
  • Componentes Pequeños: Divide en componentes pequeños y reutilizables, y prioriza la composición sobre la herencia.
  • Detecta Cambios Manualmente: Usa ChangeDetectorRef o el nuevo ɵmarkDirty solo cuando sea necesario.
  • Async Pipe y OnPush: Usa el pipe async y la estrategia de detección de cambios OnPush para máximo rendimiento.