custom changedetectorref changedetection change javascript angular angular2-changedetection

javascript - changedetection - Angular2 zone.run() vs ChangeDetectorRef.detectChanges()



changedetectorref angular (2)

Digamos que tengo una function noificationHandler() en mis servicios que está fuera del contexto de angular. noificationHandler() es invocado por un tercero y noificationHandler() básicamente consume una matriz y la emite a los componentes que se han suscrito a su servicio.

servicio.ts

public mySubject: Subject<any> = new Subject(); public myObservable = this.mySubject.asObservable(); constructor() { this.registry.subscribe("notification.msg",this.noificationHandler.bind(this)); } noificationHandler(data) { this.publishUpdate(data) } publishUpdate(data) { this.mySubject.next(data); }

componente.ts

constructor(private service: myService) { this.service.myObservable.subscribe(list => { this.list = list; }); }

^^^ En este punto, la plantilla no se actualiza con los nuevos datos.

Como el "notification.msg" está fuera de la zona angular, la detección del cambio del ángulo no se ejecuta cuando se invoca este evento ("notification.msg") .

Ahora hay 2 formas de invocar la detección de cambios.

1) noificationHandler() el noificationHandler() dentro de la zona de angular.run ()

this.registry.subscribe("a2mevent.notification.msg", this.ngZone.run(() => this.noificationHandler.bind(this)));

2) Preguntando individualmente al componente para detectar cambios.

constructor(private service: myService, private ref: ChangeDetectorRef) { this.service.myObservable.subscribe(list => { this.list = list; this.ref.detectChanges(); // <==== manually invoking change detection }); }

Ambas opciones funcionan! Y mi estructura de componentes es la siguiente

A --> root component B C D // my component is here (4 levels of nesting)

Preguntas -

1) DetectChanges () detectará cambios solo para sus propios componentes o también ejecutará la detección de cambios en componentes secundarios?

2) ¿zone.run () activará la detección de cambios de todos los componentes desde la raíz hasta la hoja?

Entre zone.run () y detectChanges () tengo curiosidad por saber cuál es el mejor rendimiento .


Ambas son cosas totalmente diferentes.

NgZone es una biblioteca que proporciona zonas para su aplicación para que pueda ejecutar las instancias en múltiples ámbitos.

ChangeDetection siempre es de padre a hoja como A> B> C Cuando llama a detectChanges () invocará el componente actual y sus componentes hijos también. Por lo tanto, este es el mejor método para usar OnPush changesdetectionStrategy para los componentes de hoja, por lo que solo detectarán los cambios cuando se actualicen las entradas.

Además, ApplicationRef es similar a ChangeDetector; la diferencia es que detectará cambios desde el componente raíz hasta el último componente secundario.

ChaneDetection y NgZone es la mejor combinación siempre para evitar la innecesaria ChangeDetection


ApplicationRef.tick (igual que setTimeout() ) y zone.run() causa la detección de cambios en toda la aplicación. Además, los detectores de eventos agregados en Angular o Angular (mediante los enlaces de vista o @HostBinding() provocan la detección de cambios en toda la aplicación.

ChangeDetectorRef.detectChanges ejecuta la detección de cambios para un componente específico (y sus descendientes, si corresponde, por ejemplo, debido a los enlaces de entrada)

Si algún código que se ejecuta fuera de la zona de Angular llama al código de Angular y cambia el estado, entonces la detección de cambios debe invocarse explícitamente porque Angular no tiene forma de saber que el estado cambió.

Si el cambio al estado es local a un componente (por ejemplo, un campo de componentes), ChangeDetectorRef.detectChanges o ChangeDetectorRef.markforCheck son más eficientes.

Si la llamada desde el exterior, por ejemplo, navega a una ruta diferente, esto puede tener consecuencias para una serie de componentes, y tampoco está claro cuándo se completa el cambio completo de la ruta porque podría causar llamadas asíncronas (y llamadas de devoluciones de llamada). En este caso, zone.run() es la mejor opción, porque el código invocado directa e indirectamente (como devoluciones de llamada de observables y promesas) se ejecutará dentro de la zona de Angular y Angular los reconocerá e invocará la detección de cambios automáticamente.