Meine Ember-App hat eine Route, die zwei verschiedene Komponenten und einen Controller mit einer index.hbs-Vorlage enthält.
So sieht es aus:
1) Ein Benutzer kann mehrere Filter aus den Dropdown-Listen der Filterkomponente auswählen
2) Das DataGrid ist eine separate Komponente vom Filter
3) Ein Benutzer kann mehrere Zeilen aus dem DataGrid auswählen, indem er die Kontrollkästchen
aktiviert4) Schaltfläche "Benutzerdefinierten Bericht erstellen" feuert "sendAction" auf den Controller der Route
Diese Daten sind nicht modellspezifisch ... es sind nur temporäre Daten, die benötigt werden, bevor ich einen benutzerdefinierten Bericht erstellen kann.
Best Practices von Ember sind "Herunterfahren von Daten / Aktionen nach oben". Nach dem, was ich gelesen habe, sollten Sie nicht versuchen, über einen Controller auf eine Komponente zuzugreifen.
Das Problem ist jedoch, dass die Methode createCustomReport im Controller Zugriff auf alle Filter benötigt, die in der Filterkomponente zusammen mit allen Zeilen ausgewählt wurden, die in der Rasterkomponente überprüft wurden .
Mein erster Instinkt besteht darin, die Eigenschaften der Komponente selbst festzulegen - sie muss ihren eigenen Zustand beibehalten - und dann vom Controller eine Referenz auf die Komponente erhalten, um ihren Status zu erhalten, bevor sie an die Berichtsfunktion übergeben wird.
Aber anscheinend ist das ein Nein-Nein.
Hier ist meine aktuelle Lösung:
Jedes Mal, wenn ich einen Filter auswähle, gibt es eine sendAction, die von der Komponente zum Controller hochgleitet und eine benutzerdefinierte Eigenschaft auf dem Controller setzt.
Jedes Mal, wenn ich ein Kontrollkästchen aus dem Raster auswähle, wechselt auch ein anderer sendAction zur Komponente, blubbert dann zum Controller und setzt eine benutzerdefinierte Eigenschaft für ausgewählte Rasterzeilen auf dem Controller.
Wenn ich dann auf "createCustomReport" klicke, hat die Methode, die im Controller ausgelöst wird, Zugriff auf die Eigenschaften, die ich zuvor festgelegt habe - weil sie alle jetzt auf dem Controller sind.
Es sieht also ungefähr so aus:
%Vor%Hier ist mein Problem mit diesem
Ich greife nicht direkt vom Controller auf die Komponenten zu, aber indem ich das "Actions Up" -Prinzip verwende, setze ich Eigenschaften auf dem Controller, die für die Ansicht spezifisch sind.
Da ich von einem Sencha ExtJS-Hintergrund komme, wo Controller Referenzen auf ihre Ansichten haben, finde ich das sehr seltsam.
Wenn ich keine Referenzen zu Komponenten bekomme, sollte ich meinen Controller von seinen Ansichten entkoppeln ... aber da alle Eigenschaften, die ich einstelle, normalerweise in der Ansicht sind, wird der Controller schließlich mehr an die Ansicht gekoppelt, als wenn ich nur einen Verweis auf die Komponente erhalten würde.
Wird dies in Ember als "best practice" betrachtet, oder gibt es einen besseren Weg für mich, die Daten all dieser separaten Komponenten abzurufen, um die createCustomReport-Methode auszulösen?
Okay, ich denke, ich habe es geschafft, mein eigenes Problem zu lösen und zu der Ember-Methode zu kommen.
Ich habe zwei verschiedene Lösungen gefunden, von denen jede ihre Vorzüge hat. Außerdem habe ich 2 kleine Ember Twiddle Mini-Tutorials zur Lösung der Statusausbreitung und Teilen von Komponentendaten erstellt.
Beide Lösungen entsprechen vollständig der Ember 2.6-Methode: Keine Controller erforderlich .
Ich habe eine einfache Filmliste erstellt, die hier angesehen werden kann: Ссылка
Indem Sie den Kommentaren in den Dateien folgen und über das Ember Twiddle oben schauen, sollten alle Ihre Fragen beantwortet werden, wie Sie das umsetzen können.
Da es sich bei einem Service um einen Singleton handelt, kann ich ihn in meine Komponenten und in meine Route einfügen. Der einzige Zweck besteht darin, die Daten der zugehörigen Komponente zu pflegen.
So sieht die Komponente aus:
%Vor%So sieht der Service aus:
%Vor%Hier ist die Datei mit den Lenkergriffen der Komponente:
%Vor%Und so sieht die Route aus:
%Vor%Vorteile der Servicelösung:
Da ich ein Singleton bin, kann ich überall in der Anwendung auf die Daten dieser Komponente zugreifen.
Nachteile der Servicelösung:
Ich muss das in jede Datei injizieren, in der ich es verwenden möchte - dadurch entstehen Abhängigkeiten, während ich gehe. Die andere Lösung besteht darin, eine Ember Initializer-Klasse zu verwenden, die sie beim Start der App automatisch in Routes, Controller oder Komponenten einfügt. Natürlich bedeutet das, dass es in jede einzelne Instanz von dem, in das injiziert wird, übertrieben sein könnte.
Der zweite Ember Twiddle ist eine einfache Restaurantliste, die zeigt, wie man den Status ohne die Notwendigkeit eines Dienstes propagiert:
Hier ist die Datei mit den Lenkergriffen der Komponente:
%Vor%Hier ist die Routendatei:
%Vor%Und hier ist die Komponentendatei:
%Vor%Beachten Sie, dass die Route eine undefinierte Statuseigenschaft enthält: 'currentSelectedRestaurant'.
Dies könnte leicht ein Objekt mit mehreren Eigenschaften oder ein Array sein.
Sie könnten auch einen generischen Namen wie "componentState" haben und alles speichern, was Sie aus einer beliebigen Komponente senden möchten: Optionen, die in einer gefilterten Liste oder ausgewählten Elementen aus einem Grid geprüft werden.
Vorteile der Nichtbenutzung eines Dienstes:
Es ist einfacher zu machen. Verwenden Sie sendAction () in Ihrer Komponente, um zum Router zu gelangen. Und es gibt keine zusätzlichen Dateien oder Abhängigkeiten.
Nachteile, wenn Sie keinen Service verwenden
Da die Modelldaten von der Routenebene herunter fließen, können Sie nicht auf den Status zugreifen, wenn Sie Routen ändern.
Jede Lösung ist machbar, also überlasse ich es Ihnen, herauszufinden, was am besten funktioniert.
Auch das nenne ich noch nicht die Antwort, denn jemand anders hat vielleicht eine bessere Lösung und es wäre schön, ein Feedback dazu zu bekommen.
Tags und Links javascript ember.js ember-cli