2016-04-23 3 views
2

Betrachten Sie diese plunkerHat `Change: ChangeDetectionStrategy.OnPush` in angular2 funktioniert nur in eine Richtung: oben-> unten?

import {Component, OnInit, Input, OnChanges, DoCheck, ChangeDetectionStrategy, EventEmitter} from 'angular2/core' 

@Component({ 
    selector: 'child11', 
    template: ` 
     <button (click)="change_obj()">Button in Child11</button> 
     <div>This is child11: {{my_obj11['name']}}</div> 
    `, 
    changeDetection: ChangeDetectionStrategy.OnPush 
}) 
export class Child11 { 
    @Input() 
    my_obj11: Object; 

    change_obj(){ 
    this.my_obj11['name'] = 'some other name'; 
    } 
} 

@Component({ 
    selector: 'child1', 
    template: ` 
     <child11 [my_obj11]="my_obj1"></child11> 
     <div>This is child1: {{my_obj1['name']}}</div> 
    `, 
    changeDetection: ChangeDetectionStrategy.OnPush, 
    directives: [Child11] 
}) 
export class Child1 { 
    @Input() 
    my_obj1: Object; 
} 

@Component({ 
    selector: 'parent', 
    template: ` 
    <div> 
     <child1 [my_obj1]="my_obj" ></child1> 
     This is my_obj in parent: {{my_obj['name']}} 
    </div> 
    `, 
    directives: [Child1] 
}) 
export class App { 
    my_obj: Object = {'name': 'name1'}; 
} 

Hier ist die Beziehung zwischen den Komponenten

ist
Parent 
    | 
Child1 
    | 
Child11 

Wir stellen fest, dass Child1 haben changeDetection: ChangeDetectionStrategy.OnPush

Der obige Code ganz einfach, parent ein Objekt zu child1 senden, sendet das exakt gleiche Objekt zu child11.

child11 dann aktualisieren, um die primitive des Objekts.

Wir sehen, dass beide parent und child1 ‚s Objekt selbst aktualisiert wird, obwohl child1changeDetection: ChangeDetectionStrategy.OnPush

habe ich changeDetection: ChangeDetectionStrategy.OnPush nur eine funktioniert Art und Weise zu raten bin: von oben nach unten.

Stimmt das?

Wenn dies der Fall ist, gibt es einen Grund dafür?

Antwort

3

Nach Savkin's blog post (na ja, es in einem Kommentar begraben liegt zu @vivainio),
mit OnPush, Angular wird nur die Komponente nach Änderungen (dh überprüfen Sie die Vorlage Bindungen), wenn

  • jeder seine Eingabeeigenschaften ändert sich
  • es löst ein Ereignis (z. B. einen Klick auf die Schaltfläche)
  • ein Observable löst ein Ereignis aus [Beachten Sie, dass dies nicht ganz korrekt ist. Die beobachtbare muss | async in der Ansicht/Vorlage, um zur Änderungserkennung verwenden, auszuführen. Siehe Kommentare zu this answer für weitere Informationen.]

Wenn eine dieser Bedingungen erfüllt sind, Angular wird auch „mark“ alle Komponenten bis der Baum an der Wurzel Komponente als Änderungserkennung benötigen. Es wird dann die Änderungserkennung ausgeführt. Alle Vorgängerkomponenten, auch wenn sie für die Strategie OnPush konfiguriert sind, werden auf Änderungen geprüft, da sie derzeit "markiert" sind. Diese

erklärt, warum die Ansichten für die Eltern/App und Child1 Komponenten als Ergebnis eines Ereignisses aktualisiert werden Brennen in der Komponente Child11.


Dieses „den Baum markieren“ Funktionalität ist, und für den genauen Grund/Szenario zeigen Sie in Ihrem Beispielcode – dh ändert eine Komponente einige Anwendungsdaten und Vorfahre Komponenten haben Datenbindungen für das gleiche Daten in ihren Ansichten. Wie stellt Angular sicher, dass die Ansichten aktualisiert werden? Es muss alle Vorfahren bis zur Wurzelkomponente "markieren", so dass bei der Änderungserkennung alle diese Komponenten überprüft werden.

Beachten Sie, dass diese alle Szenarien nicht jedoch decken. Angenommen, die geänderten Anwendungsdaten sind auch in einer Komponentensicht in einem anderen, nicht verwandten "Zweig" des Komponentenbaums vorhanden, und dieser Zweig verwendet OnPush.Diese Komponentenansicht wird nicht aktualisiert.

1

Ich weiß, es ist eine Weile her, aber ich stieß auf ein ähnliches Problem. Daher möchte ich betonen, dass OnPush nicht immer die Art und Weise ändert, wie die Kommunikation zwischen Eltern und Kindern funktioniert. Wenn die Eigenschaft @Input der untergeordneten Komponente ein Objekt (Referenztyp) ist, wird OnChanges auf dem untergeordneten Element nur dann ausgelöst, wenn sich der Verweis ändert (ein neues Objekt wird erstellt), unabhängig von OnPush. OnPush macht mehr Sinn für die Vorlage Bindung, Anfrage Winkel zu tun value equality oder einfach nur Referenzen vergleichen. Bitte korrigieren Sie mich, wenn ich falsch lag.

Verwandte Themen