So hängen Sie ngrx / store mit einem eckigen Router Guard an

8

Ich bin ein Anfänger mit ngrx / store und das ist mein erstes Projekt, das es benutzt.

Ich habe mein eckiges Projekt erfolgreich mit ngrx / store eingerichtet und kann eine Ladeaktion nach der Initialisierung meiner Hauptkomponente wie folgt auslösen:

ngOnInit() { this.store.dispatch({type: LOAD_STATISTICS}); }

Ich habe einen Effekt zum Laden der Daten eingerichtet, wenn diese Aktion ausgelöst wird:

%Vor%

Mein Reduzierer sieht so aus:

%Vor%

Obwohl das funktioniert, kann ich mir nicht vorstellen, wie man das mit einem Router-Wächter benutzt, da ich die LOAD_ACTION nur einmal senden muss.

Auch, dass eine Komponente eine LOAD-Aktion absetzen muss, um anfängliche Daten zu laden, klingt für mich nicht richtig. Ich würde erwarten, dass das Geschäft selbst weiß, dass es Daten laden muss und ich keine Aktion zuerst versenden muss. Wenn dies der Fall wäre, könnte ich die ngOnInit () -Methode in meiner Komponente löschen.

Ich habe mir schon die ngrx-Beispiel-App angesehen, aber ich habe nicht wirklich verstanden, wie das funktioniert.

BEARBEITEN:

Nach dem Hinzufügen eines Auflösungsschutzes, der den beobachtbaren ngrx-Speicher zurückgibt, wird die Route nicht aktiviert. Hier ist der Entschluss:

%Vor%

Dies ist die Route:

%Vor%     
Marco Rinck 28.02.2017, 11:53
quelle

5 Antworten

5

Ich habe es gerade nach wertvollen Eingaben von AngularFrance selbst gelöst. Da ich noch ein Anfänger bin, weiß ich nicht, ob das so sein soll, aber es funktioniert.

Ich habe einen CanActivate Guard wie folgt implementiert:

%Vor%

Die Methode canActivate (...) versendet zuerst eine Aktion zum Laden der Daten. In waitForDataToLoad () filtern wir, dass die Daten bereits vorhanden und nicht leer sind (ein Implementierungsdetail meiner Geschäftslogik).

Nachdem dies wahr ist, rufen wir switchMap auf, um ein Observable von true zurückzugeben.

    
Marco Rinck 28.02.2017, 16:02
quelle
6

Ich verstehe nicht ganz, warum Sie die aufgelösten Daten über den Resolver an Ihre Komponente senden würden. Der Hauptgrund für die Einrichtung eines ngrx-Speichers besteht darin, eine einzige Datenquelle zu haben. Also, was Sie hier einfach machen wollen, ist sicherzustellen, dass die Daten wahr sind. Ruhe, die Komponente kann die Daten aus dem Speicher mit einem Selektor abrufen.

Ich kann sehen, dass Sie LOAD_ACTION von der Methode ngOnInit Ihrer Komponente aufrufen. Sie können keine Aktion zum Auflösen von Daten aufrufen, die dann zu der Komponente führt, auf Init , von der Sie die Aktion nennen! Aus diesem Grund lädt Ihr Router die Route nicht.

Nicht sicher, ob Sie das verstanden haben, aber es macht Sinn!

In einfachen Worten, was Sie tun, ist dies. Du sperrst einen Raum ein und schiebst dann den Schlüssel durch die Lücke unter der Tür und fragst dich dann, warum sich die Tür nicht öffnet.

Behalte den Schlüssel bei dir!

Die Auflösungsmethode des Wächters sollte LOAD_ACTION aufrufen. Dann sollte die Auflösung warten, bis die Daten geladen sind, und dann sollte der Router mit der Komponente fortfahren.

Wie machst du das?

Die anderen Antworten sind das Einrichten von Abonnements, aber das wollen Sie nicht in Ihren Wachen tun. Es ist nicht gut, sich in Wächtern zu registrieren, da sie dann abgemeldet werden müssen. Wenn die Daten jedoch nicht aufgelöst werden oder die Wächter den falschen Wert zurückgeben, kann der Router sich nie wieder abmelden und wir haben ein Durcheinander.

Also, benutze take(n) . Dieser Operator wird n -Werte aus dem Abonnement übernehmen und das Abonnement automatisch beenden.

Außerdem benötigen Sie in Ihren Aktionen LOAD_STATISTICS_SUCCESS und LOAD_STATISTICS_FAIL . Da Ihre Service-Methode fehlschlagen kann!

Im Reducer State benötigen Sie eine Eigenschaft loaded , die zu true wird, wenn der Serviceaufruf erfolgreich ist und LOAD_STATISTICS_SUCCESS action aufgerufen wird.

Fügen Sie einen Selektor in den Hauptreduzierer, getStatisticsLoaded , hinzu und in Ihrem Fall würde Ihr Setup wie folgt aussehen:

%Vor%

}

Nur wenn die geladene Eigenschaft auf "true" geändert wird, lässt der Filter den Stream weiterlaufen. take wird den ersten Wert annehmen und weitergeben. Zu diesem Zeitpunkt ist die Lösung abgeschlossen und der Router kann fortfahren.

Auch hier wird take das Abonnement beenden.

    
notANerdDev 01.04.2017 14:16
quelle
4

Ich nehme an, mit "Router Guard" meinst du einen resolve guard? Wie möchten Sie, dass die Daten geladen werden, bevor die Route aktiviert wird?

Wenn ja, dann sollte alles gut zusammenspielen:

  • Werte von ngrx / store werden als Observables verfügbar gemacht (z. B. in ihren Dokumenten store.select('counter') enthält eine Observable).
  • In Angular resolve guards können Observables zurückgeben .

Sie könnten also einfach die ngrx / store Observable aus Ihrer Entschlossenheit zurückgeben:

%Vor%

Das heißt, Ihr Setup scheint ein wenig komplex zu sein. Ich neige dazu, den Status als transiente Daten zu betrachten (minimierter Status eines Menüs, Daten, die für die Dauer der Sitzung auf mehrere Bildschirme / Komponenten aufgeteilt werden müssen, z. B. der aktuelle Benutzer), aber ich bin nicht sicher, dass ich ein großes Stück Daten vom Backend in den Zustand laden würde.

Was gewinnen Sie, wenn Sie die Statistiken im Status speichern? (statt sie einfach zu laden und in einer Komponente anzuzeigen)

    
AngularChef 28.02.2017 12:26
quelle
0

Dies berücksichtigt auch eine fehlgeschlagene Anfrage:

%Vor%     
Martin Javinez 29.07.2017 20:48
quelle
0

Diese Antwort für Leute, die in dieser Situation mit ngrx / effect frustriert sind. Vielleicht besser, einfach nur Ansatz ohne ngrx / Effekte zu verwenden.

%Vor%     
alexKhymenko 13.09.2017 15:40
quelle