Problema di rilevamento modifiche: perché questo cambia quando si tratta dello stesso riferimento a un object con On Push

Ho pensato di essere abbastanza chiaro su come funziona il rilevamento del cambiamento angular dopo questa discussione: perché il rilevamento dei cambiamenti non sta accadendo qui quando [valore] è cambiato?

Ma dai un’occhiata a questo plunk: 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() { } }

Fare clic su a, è cambiato in c

Comprendo che l’evento click triggers il rilevamento delle modifiche a livello di app, ma [myData] = “testData” si riferisce ancora allo stesso object e sto utilizzando On Push on Simple, perché viene modificato?

Questo è di design.

Se hai un componente con il rilevamento delle modifiche di OnPush sua funzione detectChangesInternal non verrà triggersta se non si verifica una delle quattro cose seguenti:

1) una delle sue modifiche @Inputs

~ 2.4.x inserisci la descrizione dell'immagine qui

~ 4.xx inserisci la descrizione dell'immagine qui

Nota: @Input s deve essere presentato nel modello. Vedere il problema https://github.com/angular/angular/issues/20611 e commentare

2) un evento legato viene triggersto dal componente ( che è il tuo caso )

Avvertenze: c’è qualche differenza tra il 2 e il 4

Angular ChangeDetectionStrategy.OnPush con componente figlio che emette un evento

~ 2.4.x inserisci la descrizione dell'immagine qui

~ 4.xx inserisci la descrizione dell'immagine qui

3) contrassegni manualmente il componente da controllare ( ChangeDetectorRef.markForCheck() )

4) pipe async chiama 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


In altre parole, se imposti OnPush per il componente, dopo il primo controllo, lo stato del componente verrà modificato da CheckOnce a Checked dopodiché sarà in attesa che non venga modificato lo stato. Accadrà in una delle tre cose sopra.

Guarda anche:

Ci sono anche buone spiegazioni su come funziona il rilevamento del cambiamento angular2:

Ecco l’ esempio dal vivo (grazie a Paskal) che spiega il rilevamento del cambio onPush . ( Comp16 è simile al tuo componente. Puoi fare clic su questa casella).