Sollten die Geschäfte ihren eigenen Status beibehalten und dabei Netzwerk- und Datenspeicherdienste aufrufen können ... In diesem Fall handelt es sich bei den Aktionen nur um dumme Nachrichtenpassanten.
-ODER-
... sollten die Speicher dumme Empfänger unveränderlicher Daten aus den Aktionen sein (und die Aktionen sind diejenigen, die Daten zwischen externen Quellen abrufen / senden? Der Speicher würde in diesem Fall als Ansichtsmodelle fungieren und in der Lage sein, ihre zu aggregieren / zu filtern Daten, bevor sie ihre eigene Zustandsbasis auf die unveränderlichen Daten setzen, die sie von der Aktion erhalten haben.
Es scheint mir, dass es das eine oder andere sein sollte (und nicht eine Mischung aus beiden). Wenn ja, warum wird einer dem anderen vorgezogen / empfohlen?
quelle
Antworten:
Ich habe gesehen, dass das Flussmuster in beide Richtungen implementiert wurde, und nachdem ich beides selbst getan habe (zunächst mit dem früheren Ansatz), glaube ich, dass Speicher dumme Empfänger von Daten aus den Aktionen sein sollten und dass die asynchrone Verarbeitung von Schreibvorgängen in der Aktionsersteller. ( Asynchrone Lesevorgänge können unterschiedlich gehandhabt werden .) Nach meiner Erfahrung hat dies einige Vorteile in der Reihenfolge ihrer Wichtigkeit:
Ihre Geschäfte werden vollständig synchron. Auf diese Weise ist Ihre Geschäftslogik viel einfacher zu befolgen und sehr einfach zu testen. Instanziieren Sie einfach ein Geschäft mit einem bestimmten Status, senden Sie ihm eine Aktion und prüfen Sie, ob sich der Status wie erwartet geändert hat. Darüber hinaus besteht eines der Kernkonzepte von Flux darin, kaskadierende Versendungen und mehrere Versendungen gleichzeitig zu verhindern. Dies ist sehr schwierig, wenn Ihre Filialen eine asynchrone Verarbeitung durchführen.
Alle Aktionsversendungen erfolgen von den Aktionserstellern. Wenn Sie asynchrone Vorgänge in Ihren Filialen ausführen und die Aktionshandler Ihrer Filialen synchron halten möchten (und dies sollten Sie tun, um die Garantien für den Fluss-Einzelversand zu erhalten), müssen Ihre Filialen als Reaktion auf asynchrone Aktionen zusätzliche SUCCESS- und FAIL-Aktionen auslösen wird bearbeitet. Wenn Sie diese Versendungen stattdessen in die Aktionsersteller einfügen, können Sie die Jobs der Aktionsersteller und der Speicher trennen. Darüber hinaus müssen Sie nicht in Ihrer Geschäftslogik stöbern, um herauszufinden, woher die Aktionen gesendet werden. Eine typische asynchrone Aktion in diesem Fall könnte ungefähr so aussehen (ändern Sie die Syntax der
dispatch
Aufrufe basierend auf der Art des verwendeten Flusses):Logik, die andernfalls über verschiedene Aktionen hinweg dupliziert werden könnte, sollte in ein separates Modul extrahiert werden. In diesem Beispiel wäre dies das Modul
SomeDataAccessLayer
, das die eigentliche Ajax-Anforderung ausführt.Sie benötigen weniger Action-Ersteller. Das ist weniger eine große Sache, aber schön zu haben. Wie in Nr. 2 erwähnt, müssen Sie zusätzliche Aktionen auslösen, um die Ergebnisse asynchroner Vorgänge zu verarbeiten, wenn Ihre Filialen über eine synchrone Versandabwicklung verfügen (und dies sollten). Durch das Ausführen der Versendungen in den Aktionserstellern kann ein einzelner Aktionsersteller alle drei Aktionstypen auslösen, indem er das Ergebnis des asynchronen Datenzugriffs selbst verarbeitet.
quelle
"SOME_ACTION"
), verwende eine API, um eine Anfrage (SomeDataAccessLayer.doSomething(userId)
) zu stellen, die ein Versprechen zurückgibt, und.then
versende in den beiden Funktionen zusätzliche Aktionen. Der Anforderungsstatus kann (mehr oder weniger) dem Speicherstatus zugeordnet werden, wenn die Anwendung den Status des Status kennen muss. Wie diese Karte der App entspricht (z. B. hat jeder Kommentar einen individuellen Fehlerstatus, a la Facebook, oder es gibt eine globale Fehlerkomponente)Ich habe diese Frage an die Entwickler auf Facebook getwittert und die Antwort von Bill Fisher war:
quelle
a call from store works better when action triggers from non-human driver
?Die Geschäfte sollten alles tun, einschließlich des Abrufs von Daten und der Signalisierung an Komponenten, dass die Daten des Geschäfts aktualisiert wurden. Warum? Denn Aktionen können dann leicht, wegwerfbar und austauschbar sein, ohne das wichtige Verhalten zu beeinflussen. Alle wichtigen Verhaltensweisen und Funktionen finden im Geschäft statt. Dies verhindert auch das Duplizieren von Verhalten, das sonst in zwei sehr ähnlichen, aber unterschiedlichen Aktionen kopiert würde. Die Geschäfte sind Ihre einzige Quelle für den Umgang mit der Wahrheit.
In jeder Flux-Implementierung, die ich gesehen habe, sind Aktionen im Grunde genommen Ereigniszeichenfolgen, die in Objekte umgewandelt wurden, wie traditionell ein Ereignis mit dem Namen "anchor: clicked", aber in Flux wird es als AnchorActions.Clicked definiert. Sie sind sogar so "dumm", dass die meisten Implementierungen separate Dispatcher-Objekte haben, um die Ereignisse tatsächlich an die Geschäfte zu senden, die sie abhören.
Persönlich mag ich die Implementierung von Flux durch Reflux, bei der es keine separaten Dispatcher-Objekte gibt und Action-Objekte den Versand selbst durchführen.
Bearbeiten: Facebooks Flux holt tatsächlich "Action Creators" ein, damit sie intelligente Aktionen verwenden. Sie bereiten die Nutzlast auch über die Geschäfte vor:
https://github.com/facebook/flux/blob/19a24975462234ddc583ad740354e115c20b881d/examples/flux-chat/js/actions/ChatMessageActionCreators.js#L27 (Zeile 27 und 28)
Der Rückruf nach Abschluss würde diesmal eine neue Aktion mit den abgerufenen Daten als Nutzlast auslösen:
https://github.com/facebook/flux/blob/19a24975462234ddc583ad740354e115c20b881d/examples/flux-chat/js/utils/ChatWebAPIUtils.js#L51
Ich denke, das ist die bessere Lösung.
quelle
Ich werde ein Argument für "dumme" Aktionen vorbringen.
Indem Sie die Verantwortung für das Sammeln von Ansichtsdaten in Ihre Aktionen übernehmen, koppeln Sie Ihre Aktionen mit den Datenanforderungen Ihrer Ansichten.
Im Gegensatz dazu ermöglichen generische Aktionen, die die Absicht des Benutzers oder einen Statusübergang in Ihrer Anwendung deklarativ beschreiben , jedem Geschäft, das auf diese Aktion reagiert, die Absicht in einen Status umzuwandeln, der speziell auf die abonnierten Ansichten zugeschnitten ist.
Dies bietet sich für zahlreichere, aber kleinere, spezialisiertere Geschäfte an. Ich argumentiere für diesen Stil, weil
Der Zweck eines Geschäfts besteht darin, Daten für Ansichten bereitzustellen. Der Name "Aktion" deutet darauf hin, dass der Zweck darin besteht, eine Änderung in meiner Anwendung zu beschreiben.
Angenommen, Sie müssen einer vorhandenen Dashboard-Ansicht ein Widget hinzufügen, das einige ausgefallene neue aggregierte Daten anzeigt, die Ihr Backend-Team gerade eingeführt hat.
Bei "intelligenten" Aktionen müssen Sie möglicherweise Ihre "Aktualisierungs-Dashboard" -Aktion ändern, um die neue API zu verwenden. "Das Dashboard aktualisieren" im abstrakten Sinne hat sich jedoch nicht geändert. Die Datenanforderungen Ihrer Ansichten haben sich geändert.
Mit "dummen" Aktionen können Sie einen neuen Speicher hinzufügen, den das neue Widget verwenden soll, und ihn so einrichten, dass er beim Empfang des Aktionstyps "Aktualisierungs-Dashboard" eine Anforderung für die neuen Daten sendet und diese verfügbar macht das neue Widget, sobald es fertig ist. Für mich ist es sinnvoll, dass, wenn die Ansichtsebene mehr oder andere Daten benötigt, die Dinge, die ich ändere, die Quellen dieser Daten sind: Speicher.
quelle
Gaerons Flux- React -Router-Demo bietet eine nette Utility-Variante des 'richtigen' Ansatzes.
Ein ActionCreator generiert ein Versprechen von einem externen API-Dienst und übergibt das Versprechen und drei Aktionskonstanten an eine
dispatchAsync
Funktion in einem Proxy / erweiterten Dispatcher.dispatchAsync
wird immer die erste Aktion auslösen, z. B. 'GET_EXTERNAL_DATA', und sobald das Versprechen zurückgegeben wird, wird entweder 'GET_EXTERNAL_DATA_SUCCESS' oder 'GET_EXTERNAL_DATA_ERROR' gesendet.quelle
Wenn Sie eines Tages eine Entwicklungsumgebung haben möchten, die mit der in Bret Victors berühmtem Video " Inventing on Principle" vergleichbaren vergleichbar ist , sollten Sie lieber dumme Speicher verwenden, die nur eine Projektion von Aktionen / Ereignissen innerhalb einer Datenstruktur ohne Nebenwirkungen sind. Es wäre auch hilfreich, wenn Ihre Filialen tatsächlich Mitglied derselben globalen unveränderlichen Datenstruktur wären, wie in Redux .
Weitere Erklärungen finden Sie hier: https://stackoverflow.com/a/31388262/82609
quelle