Published

- 3 min read

Angular No Actualiza la Vista

img of Angular No Actualiza la Vista

Angular No Actualiza la Vista:

El Dilema de ChangeDetectionStrategy.OnPush

Si alguna vez has usado ChangeDetectionStrategy.OnPush en Angular, seguro te has topado con un problema curioso: los valores en la vista no se actualizan automáticamente a menos que haya un cambio explícito en las propiedades marcadas con @Input().

Esto puede ser un dolor de cabeza cuando necesitas actualizar datos en tiempo real, como un contador, la hora actual o cualquier otro valor dinámico. Aunque el dato realmente esté cambiando en el código, Angular no lo detecta por sí solo, y la vista se queda congelada.

🚨 El Problema en Acción

Imagina que tienes una variable remainingTime que debería actualizarse cada segundo, pero en la vista sigue mostrando el mismo valor:

   import { Component, OnInit, ChangeDetectionStrategy } from '@angular/core';

@Component({
  selector: 'app-info',
  template: `<p>Tiempo restante: {{ remainingTime }}</p>`,
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class InfoComponent implements OnInit {
  remainingTime: string = '';

  ngOnInit(): void {
    setInterval(() => {
      this.remainingTime = new Date().toLocaleTimeString();
    }, 1000);
  }
}

🛠️ Solucionando el Problema con ChangeDetectorRef

Este es un problema común cuando trabajamos con valores dinámicos, como fechas, contadores o datos en tiempo real. En este caso, tenemos un reloj (remainingTime) que debería actualizarse cada segundo, pero como Angular no detecta el cambio por sí mismo, la vista se queda estática.


ChangeDetectorRef.markForCheck()

La solución pasa por marcar el componente para su actualización en el próximo ciclo de detección de cambios usando markForCheck(). Esto evita que la vista quede congelada y nos permite seguir beneficiándonos de la optimización de OnPush.

Aquí está el código corregido:

   import { ChangeDetectorRef, Component, OnInit, ChangeDetectionStrategy } from '@angular/core';

@Component({
  selector: 'app-info',
  template: `<p>Tiempo restante: {{ remainingTime }}</p>`,
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class InfoComponent implements OnInit {
  remainingTime: string = '';

  constructor(private cdRef: ChangeDetectorRef) { }

  ngOnInit(): void {
    setInterval(() => {
      this.remainingTime = new Date().toLocaleTimeString();
      this.cdRef.markForCheck();
    }, 1000);
  }
}

Conclusión

Cuando trabajamos con ChangeDetectionStrategy.OnPush en Angular, la vista no se actualiza automáticamente si los cambios ocurren dentro del componente y no provienen de un @Input(). Esto puede ser un problema en casos donde necesitamos actualizar valores dinámicamente, como un contador o un reloj en tiempo real.

La solución es inyectar ChangeDetectorRef y usar markForCheck() dentro de setInterval(), lo que le indica a Angular que debe actualizar la vista en el próximo ciclo de detección de cambios, sin afectar el rendimiento de OnPush.

Con esta estrategia, los valores se refrescarán correctamente sin necesidad de que el usuario interactúe o recargue la página, logrando una experiencia más fluida y eficiente.

Related Posts

There are no related posts yet. 😢