Problema de detección de cambios: ¿por qué cambia esto cuando es la misma referencia de objeto con On Push?

Pensé que tenía bastante claro cómo funciona la detección de cambio angular después de esta discusión: ¿por qué la detección de cambios no ocurre aquí cuando [valor] cambió?

Pero eche un vistazo a este plan: https://plnkr.co/edit/jb2k7U3TfV7qX2x1fV4X?p=preview

@Component({ selector: 'simple', template: ` 
{{myData[0].name}}
`, changeDetection: ChangeDetectionStrategy.OnPush }) export class Simple { public @Input() myData; constructor() { } public onClick() { } }

Haga clic en a, ha cambiado a c

Entiendo que el evento click activa la detección de cambios en el nivel de la aplicación, pero [myData] = “testData” todavía se está refiriendo al mismo objeto, y estoy usando On Push on Simple, ¿por qué se cambia?

Eso es por diseño.

Si tiene un componente con OnPush Detection, su función detectChangesInternal no se activará a menos que ocurra una de detectChangesInternal cuatro cosas:

1) uno de sus cambios de entrada

~ 2.4.x enter image description here

~ 4.xx enter image description here

Nota: @Input s se debe presentar en la plantilla. Ver el problema https://github.com/angular/angular/issues/20611 y comentar

2) un evento vinculado se activa desde el componente ( ese es su caso )

Advertencias: Aquí hay alguna diferencia entre 2.xx y 4

Angular ChangeDetectionStrategy.OnPush con un componente secundario que emite un evento

~ 2.4.x enter image description here

~ 4.xx enter image description here

3) marca manualmente el componente que se va a verificar ( ChangeDetectorRef.markForCheck() )

4) llamadas de ChangeDetectorRef.markForCheck() asíncrono ChangeDetectorRef.markForCheck() internamente

 private _updateLatestValue(async: any, value: Object): void { if (async === this._obj) { this._latestValue = value; this._ref.markForCheck(); } } 

https://github.com/angular/angular/blob/2.4.8/modules/%40angular/common/src/pipes/async_pipe.ts#L137


En otras palabras, si configura OnPush para el componente, luego de que el estado del primer componente de verificación cambiará de CheckOnce a Checked y luego de eso estará esperando mientras no cambiemos de estado. Ocurrirá en una de las tres cosas anteriores.

Ver también:

También hay buenas explicaciones de cómo funciona la detección de cambios de angular2:

Aquí está el ejemplo en vivo (gracias a Paskal) que explica la detección de cambio de onPush . ( Comp16 parece a su componente. Puede hacer clic en esta casilla).