Vermitteln und teilen Sie Daten zwischen verschiedenen Modulen

8

Ich versuche nur, meinen Kopf um Event-getriebene JS herumzutragen, also bitte, ertragen Sie mit mir. Es gibt verschiedene Arten von Modulen in meiner App. Einige kapseln nur Daten ein, andere verwalten einen Teil des DOM. Einige Module hängen von anderen ab, manchmal hängt ein Modul vom Zustand mehrerer anderer Module ab, aber ich möchte nicht, dass sie direkt miteinander kommunizieren oder nur ein Modul an das andere weitergeben, nur um einfach darauf zugreifen zu können. Ich habe versucht, das einfachste Szenario zu erstellen, um mein Problem zu veranschaulichen (die eigentlichen Module sind natürlich viel komplexer):

Ich habe ein Datenmodul, das nur einige Daten verfügbar macht:

%Vor%

Es gibt ein configModule, das Modifikatoren für die Anzeige dieser Daten verfügbar macht:

%Vor%

Schließlich gibt es ein displayModule, das die Daten der beiden anderen Module kombiniert und rendert:

%Vor%

Ich habe auch eine einfache Implementierung von Pub-Sub, so dass ich einfach zwischen den Modulen vermitteln konnte:

%Vor%

Wie dem auch sei, so scheint es mir, dass ich einen Vermittler habe, der alle Modul-Instanzen explizit kennen muss - gibt es überhaupt einen Weg, das zu vermeiden? Ich weiß auch nicht, wie das funktionieren würde, wenn es mehrere Instanzen dieser Module gibt. Was ist der beste Weg, um globale Instanzvariablen zu vermeiden? Ich denke, meine Frage ist, was wäre der flexibelste Weg, um so etwas zu verwalten? Bin ich auf dem richtigen Weg, oder ist das völlig falsch? Tut mir leid, dass ich mit meiner Frage nicht sehr genau bin. Ich brauche nur jemanden, der mich in die richtige Richtung bringt.

    
subarachnid 23.03.2016, 22:05
quelle

2 Antworten

1

Sie sind auf dem richtigen Weg, ich werde versuchen, Ihnen den zusätzlichen Schub zu geben, von dem Sie sprechen:

Sie wollen lose Kopplung, Pub-Sub ist ein guter Weg zu gehen.

Aber Sie brauchen diesen "Vermittler" nicht wirklich, jedes Modul sollte idealerweise autonom sein und seine eigene Logik einkapseln.

Dies geschieht folgendermaßen: Jedes Modul ist vom Pubsub-Dienst abhängig, abonniert alle relevanten Ereignisse und handelt nach ihnen. Jedes Modul veröffentlicht auch Ereignisse, die für andere relevant sein könnten (Codebeispiele in einer Minute, ertragen Sie mit mir).

Ich denke, das, was Sie vielleicht hier vermissen, ist, dass Module, die Ereignisse verwenden, kaum nie nur einfache Modelle sein werden. Sie haben eine gewisse Logik und können auch ein Modell halten (das sie beim Empfang von Ereignissen aktualisieren).

Also statt eines dataModule ist es wahrscheinlicher, dass Sie ein dataLoaderModule haben, das das Datenmodell veröffentlicht (z. B. {data: 3} ), sobald das Laden beendet ist.

Eine weitere wichtige Anforderung ist die gemeinsame Nutzung von Daten unter Vermeidung globaler Instanzvariablen - dies ist ein sehr wichtiges Konzept und auch ein Schritt in die richtige Richtung. Was Sie in Ihrer Lösung dafür verpassen, ist - Dependency Injection oder zumindest ein Modulsystem, das Abhängigkeiten definieren kann.

Sie sehen, dass eine ereignisgesteuerte Anwendung nicht unbedingt bedeutet, dass jedes Teil des Codes über Ereignisse kommunizieren sollte. Ein Anwendungskonfigurationsmodell oder ein Utility-Dienst ist definitiv etwas, was ich injizieren würde (bei Verwendung von DI, wie in Angular), (bei Verwendung von AMD / CommonJS) oder Import (bei Verwendung von ES6-Modulen).
(d. h. anstatt mit einem Dienstprogramm über Ereignisse zu kommunizieren).

In Ihrem Beispiel ist es unklar, ob configModule eine statische App-Konfiguration ist oder ein Knopf, den ich von der Benutzeroberfläche aus anpassen kann. Wenn es eine statische App-Konfiguration ist - ich würde es injizieren.

Sehen wir uns nun einige Beispiele an:

Angenommen das Folgende:

  • Anstelle von dataModule haben wir dataLoaderModule
  • configModule ist ein statisches configuration Modell.
  • Wir verwenden AMD-Module (und nicht ES6-Module, die ich bevorzuge), da ich sehe, dass Sie nur ES5-Funktionen verwenden (ich sehe keine Klassen oder Konflikte).

Wir hätten:

data-loader.js (auch bekannt als dataLoaderModule)

%Vor%

configuration.js (auch bekannt als configModule)

%Vor%

display.js (auch bekannt als displayModule)

%Vor%

Das ist es.

Sie werden bemerken, dass wir hier keine globalen Variablen haben (nicht einmal Pubsub), stattdessen benötigen wir (oder injizieren) unsere Abhängigkeiten.

Hier könnten Sie fragen: "und was, wenn ich meine Konfiguration von der Benutzeroberfläche aus ändern wollte?" , also lasst uns das auch sehen:

In diesem Fall benenne ich lieber configModule in settingsDisplayModule um (nach Ihrer Namenskonvention).

Auch in einer realistischeren App werden UI-Module normalerweise ein Modell enthalten, also machen wir das auch.

Und wir können sie auch "views" anstatt "displayModules" nennen, und wir werden haben:

data-loader.js (auch bekannt als dataLoaderModule)

%Vor%

Einstellungsansicht.js (auch bekannt als settingsDisplayModule, aka config)

%Vor%

datenansicht.js (aka displayModule)

%Vor%

Und das ist es.

Ich hoffe, es hilft:)

Wenn nicht - Kommentar!

    
Yoav Aharoni 02.04.2016, 01:56
quelle
1

Sie brauchen keinen Mediator. Importieren Sie einfach Daten, Konfiguration und Anzeige und rufen Sie display(data, config) auf, wo Sie es brauchen.

%Vor%     
user6101582 27.03.2016 14:57
quelle