Angular 2 Components: Umgang mit kreisförmigen Ein- und Ausgängen

8

Aktuelle Situation:

Ich habe eine parent und eine child Komponente.

Das parent initialisiert die Daten von child mit @Input . Und das child benachrichtigt das übergeordnete Element, wenn der Benutzer die Daten mit @Output bearbeitet hat. Da die Daten unveränderlich sind , muss child die Daten zusammen mit dieser Benachrichtigung senden.

Wenn parent benachrichtigt wurde, prüft es, ob die übermittelten Daten gültig sind, und setzt es dann (das wird den neuen Wert auch an andere untergeordnete Komponenten weitergeben).

Das Problem:

Wenn Sie die neuen Daten in parent setzen, wird sie natürlich auch an die Komponente child übergeben, die gerade die Daten gesendet hat. Dies wird child ngOnChanges auslösen, was dann ein Repaint der Benutzeroberfläche auslöst.

Hintergrund:

Der parent hat mehrere verschiedene child -Komponenten, die alle auf die gleichen myItem -Daten angewiesen sind und diese Daten bearbeiten können und dann parent auf Änderungen benachrichtigen.

Hier ist eine vereinfachte Version des Codes, die das Problem zeigen sollte.

Übergeordnete Komponente:

%Vor%

Untergeordnete Komponente:

%Vor%

Wie Sie sehen können, übernimmt die child -Komponente die Daten von @Input und macht sie veränderbar. Und bevor es wieder an parent gesendet wird, wird es wieder unveränderlich gemacht.

Gibt es ein Muster, um diese kreisförmigen Ereignisse zu verhindern?

    
Benjamin M 12.08.2016, 14:18
quelle

2 Antworten

6

Ich kann mir keine Möglichkeit vorstellen, den Kreis zu verlassen, wenn wir bei der bidirektionalen Ereignisauslösung bleiben. Vor allem mit mehreren Kindern.

Methode 1

Eine Möglichkeit, an die ich denken kann, ist, dass sowohl Eltern als auch Kinder einen Share-Datendienst verwenden. Die Daten werden ein für allemal geändert, da alle Parteien die gleichen Daten verwenden.

globaldata.service.ts

%Vor%

app.module.ts (Angenommen, dies ist Ihr Root-Modul)

%Vor%

parent.component.ts (unter der Annahme, dass es sich nicht um root handelt, mehrere Instanzen, Teil von app.module)

%Vor%

child.component.ts

%Vor%

Methode 2 - Sendewarteschlange

Verwenden Sie das Subskriptions-Abonnement von RxJs wie eine Broadcast-Warteschlange. Ich habe tatsächlich ein Paket mit einem Beispiel erstellt:

Ссылка

Ссылка

Die Idee:

  1. Übergeordnete und alle untergeordneten Elemente abonnieren dieselbe Warteschlange
  2. Wenn Sie eine Sender-ID bei der Übertragung in die Warteschlange angeben, können Sie die Abonnement-ID als Absender-ID verwenden, wenn Sie mein Paket verwenden, da es sich um eine Uuid handelt.
  3. Der Rückruf überprüft die Absender-ID und führt keine Aktionen aus, wenn die Nachricht von self stammt

Parent (unter der Annahme, dass es sich nicht um root handelt, mehrere Instanzen, Teil von app.module)

%Vor%

Kind

%Vor%     
John Siu 19.08.2016, 04:31
quelle
0

Ich habe jetzt eine funktionierende (aber sehr Lösung) gefunden:

  1. child speichert den zuletzt ausgegebenen Wert in modelChange

  2. Wenn ngOnChanges aufgerufen wird, können wir die Referenzen dieser Objekte vergleichen

  3. Wenn Referenzen gleich sind, dann hat diese spezielle Komponente child den Wert

  4. erstellt

Beispiel für einen vereinfachten Code:

%Vor%

Es funktioniert wie erwartet, aber ich frage mich immer noch, ob es einen schöneren Weg gibt, weniger Code zu verwenden.

Vielleicht ist es möglich, dies mit Observable s für @Input() input ?

zu umgehen     
Benjamin M 12.08.2016 17:00
quelle