angular - Problema de detección de cambios: ¿por qué cambia esto cuando se trata de la misma referencia de objeto con On Push?
(1)
Eso es por diseño.
Si tiene un componente con detección de cambio de
OnPush
, su función
detectChangesInternal
no se activará a menos que ocurra una de las siguientes cuatro cosas:
1) uno de sus cambios
@Inputs
Nota:
@Input
s debe presentarse en plantilla.
Vea el tema
https://github.com/angular/angular/issues/20611
y
comment
2) se desencadena un evento vinculado desde el componente ( ese es su caso )
Advertencias: Aquí hay alguna diferencia entre 2.xx y 4
Angular ChangeDetectionStrategy.OnPush con componente secundario que emite un evento
3) marca manualmente el componente que se va a verificar (
ChangeDetectorRef.markForCheck()
)
4) la tubería asíncrona llama a
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 del estado del primer componente de verificación se cambiará de
CheckOnce
a
Checked
y luego esperará mientras no cambiemos el estado.
Sucederá en una de las tres cosas anteriores.
Ver también:
También hay buenas explicaciones de cómo funciona la detección de cambio angular2:
- https://blog.thoughtram.io/angular/2016/02/22/angular-2-change-detection-explained.html
- https://hackernoon.com/everything-you-need-to-know-about-change-detection-in-angular-8006c51d206f
Aquí hay un
ejemplo en vivo
(gracias a Paskal) que explica la detección de cambios
onPush
.
(
Comp16
parece a su componente. Puede hacer clic en este cuadro).
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 cambio no ocurre aquí cuando cambia [valor]?
Pero eche un vistazo a este plunk: https://plnkr.co/edit/jb2k7U3TfV7qX2x1fV4X?p=preview
@Component({
selector: ''simple'',
template: `
<div (click)="onClick()">
{{myData[0].name}}
</div>
`,
changeDetection: ChangeDetectionStrategy.OnPush
})
export class Simple {
public @Input() myData;
constructor() {
}
public onClick() {
}
}
Haga clic en a, se cambió 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 refiere al mismo objeto, y estoy usando On Push on Simple, ¿por qué se cambia?