Solución:
Puede ser que el código en su servicio de alguna manera salga de la zona de Angular. Esto rompe la detección de cambios. Esto debería funcionar:
import {Component, OnInit, NgZone} from 'angular2/core';
export class RecentDetectionComponent implements OnInit {
recentDetections: Array<RecentDetection>;
constructor(private zone:NgZone, // <== added
private recentDetectionService: RecentDetectionService) {
this.recentDetections = new Array<RecentDetection>();
}
getRecentDetections(): void {
this.recentDetectionService.getJsonFromApi()
.subscribe(recent => {
this.zone.run(() => { // <== added
this.recentDetections = recent;
console.log(this.recentDetections[0].macAddress)
});
});
}
ngOnInit() {
this.getRecentDetections();
let timer = Observable.timer(2000, 5000);
timer.subscribe(() => this.getRecentDetections());
}
}
Para conocer otras formas de invocar la detección de cambios, consulte Activar la detección de cambios manualmente en Angular
Las formas alternativas de invocar la detección de cambios son
ChangeDetectorRef.detectChanges()
para ejecutar inmediatamente la detección de cambios para el componente actual y sus hijos
ChangeDetectorRef.markForCheck()
para incluir el componente actual la próxima vez que Angular ejecute la detección de cambios
ApplicationRef.tick()
para ejecutar la detección de cambios para toda la aplicación
Originalmente es una respuesta en los comentarios de @Mark Rajcok, pero quiero colocarlo aquí como probado y funcionado como una solución usando ChangeDetectorRef, veo un buen punto aquí:
Otra alternativa es inyectar
ChangeDetectorRef
y llama
cdRef.detectChanges()
en lugar dezone.run()
. Esto podría ser más eficiente, ya que no ejecutará la detección de cambios en todo el árbol de componentes comozone.run()
lo hace. – Mark Rajcok
Entonces el código debe ser como:
import {Component, OnInit, ChangeDetectorRef} from 'angular2/core';
export class RecentDetectionComponent implements OnInit {
recentDetections: Array<RecentDetection>;
constructor(private cdRef: ChangeDetectorRef, // <== added
private recentDetectionService: RecentDetectionService) {
this.recentDetections = new Array<RecentDetection>();
}
getRecentDetections(): void {
this.recentDetectionService.getJsonFromApi()
.subscribe(recent => {
this.recentDetections = recent;
console.log(this.recentDetections[0].macAddress);
this.cdRef.detectChanges(); // <== added
});
}
ngOnInit() {
this.getRecentDetections();
let timer = Observable.timer(2000, 5000);
timer.subscribe(() => this.getRecentDetections());
}
}
Editar: Utilizando .detectChanges()
dentro de la subcibe podría dar lugar a un problema Intento de utilizar una vista destruida: detectChanges
Para solucionarlo necesitas unsubscribe
antes de destruir el componente, por lo que el código completo será como:
import {Component, OnInit, ChangeDetectorRef, OnDestroy} from 'angular2/core';
export class RecentDetectionComponent implements OnInit, OnDestroy {
recentDetections: Array<RecentDetection>;
private timerObserver: Subscription;
constructor(private cdRef: ChangeDetectorRef, // <== added
private recentDetectionService: RecentDetectionService) {
this.recentDetections = new Array<RecentDetection>();
}
getRecentDetections(): void {
this.recentDetectionService.getJsonFromApi()
.subscribe(recent => {
this.recentDetections = recent;
console.log(this.recentDetections[0].macAddress);
this.cdRef.detectChanges(); // <== added
});
}
ngOnInit() {
this.getRecentDetections();
let timer = Observable.timer(2000, 5000);
this.timerObserver = timer.subscribe(() => this.getRecentDetections());
}
ngOnDestroy() {
this.timerObserver.unsubscribe();
}
}
En mi caso, tuve un problema muy similar. Estaba actualizando mi vista dentro de una función que estaba siendo llamada por un componente principal, y en mi componente principal olvidé usar @ViewChild (NameOfMyChieldComponent). Perdí al menos 3 horas solo por este estúpido error. es decir: No necesitaba usar cualquiera de esos métodos:
- ChangeDetectorRef.detectChanges ()
- ChangeDetectorRef.markForCheck ()
- ApplicationRef.tick ()