Cuando un componente tiene OnPush, solo se actualizará si ocurre alguna de estas situaciones:

1️⃣ Cambio en un @Input()

Si el valor del @Input() cambia de referencia, Angular actualizará el componente.

Se actualiza porque cambia la referencia (objeto nuevo)

this.producto = { nombre: 'Nuevo Producto' }; 
// Esto genera una nueva referencia en memoria

No se actualiza si solo se modifica una propiedad interna

this.producto.nombre = 'Nuevo Producto';
// No cambia la referencia del objeto en memoria, Angular no lo detecta

💡 Solución: Para forzar la detección de cambios, asigna un nuevo objeto:

this.producto = { ...this.producto, nombre: 'Nuevo Producto' };

2️⃣ Eventos del DOM (click, input, etc.)

Si el componente tiene un evento como (click), (input), (change), etc., Angular detectará el cambio.

(click)="cambiarValor()">Actualizar
cambiarValor() {
  this.valor = 'Nuevo';
}

Esto siempre actualizará la vista, incluso con OnPush.


3️⃣ Uso de async en un | async pipe (Observables)

Si usas el pipe async, Angular actualizará automáticamente el componente cuando el Observable emita un nuevo valor.

{{ datos$ | async }}
datos$ = this.http.get('https://api.example.com/data');

4️⃣ Cambios manuales con markForCheck()

Si necesitas actualizar manualmente el componente, puedes usar ChangeDetectorRef.markForCheck().

constructor(private cd: ChangeDetectorRef) {}

actualizar() {
  this.valor = 'Nuevo';
  this.cd.markForCheck(); // 🔥 Forzar actualización
}

5️⃣ Cambio en una variable dentro de un setTimeout o setInterval

Si modificamos una variable dentro de setTimeout, Angular no lo detectará a menos que usemos markForCheck().

No se actualiza automáticamente

setTimeout(() => {
  this.valor = 'Nuevo';
}, 2000);

Solución con markForCheck()

setTimeout(() => {
  this.valor = 'Nuevo';
  this.cd.markForCheck();
}, 2000);

6️⃣ Cambios después de una petición HTTP manual

Si asignamos un nuevo valor después de una petición HTTP sin async, Angular no lo detectará automáticamente.

No se actualiza automáticamente

this.http.get('https://api.example.com/data').subscribe(data => {
  this.valor = data;
});

Solución con markForCheck()

this.http.get('https://api.example.com/data').subscribe(data => {
  this.valor = data;
  this.cd.markForCheck();
});

7️⃣ Re-adjuntar la detección de cambios con reattach()

Si en algún momento se desactiva la detección de cambios con cd.detach(), podemos volver a activarla con reattach().

this.cd.detach(); // 🛑 Detiene la detección
this.cd.reattach(); // 🔄 Reactiva la detección

📌 Resumen final

Si un componente tiene OnPush, solo se actualizará cuando ocurra alguno de estos eventos:

Evento ¿Actualiza con OnPush?
Cambio en un @Input() (nueva referencia) ✅ Sí
Evento del DOM (click, input, etc.) ✅ Sí
async pipe con Observables ✅ Sí
Uso de markForCheck() ✅ Sí
setTimeout o setInterval ❌ No (a menos que uses markForCheck())
HTTP Request (subscribe()) ❌ No (a menos que uses markForCheck())
detach() ❌ No
reattach() ✅ Sí

🎯 Conclusión

🔹 OnPush mejora el rendimiento porque evita que Angular revise el componente en cada ciclo de cambio.

🔹 Sin embargo, sigue actualizándose en situaciones clave como cambios en @Input, eventos del DOM o usando markForCheck().

🔹 Si necesitas forzar un cambio manualmente, usa markForCheck() o detectChanges().

Ahora tienes el conocimiento completo sobre OnPush y cuándo se actualizan los componentes. 🚀🔥