2017-06-09 8 views
1

Wie kann ich alle abgesetzte Aktion blockieren, die nach meiner Abmeldung in ngrx auslösen? Gibt es eine Art root Dispatcher, der diese Logik verarbeitet?Ngrx Abbrechen Aktionen nach Abmeldung Aktion gesendet

+0

Sie können Aktionen, die direkt an den Store gesendet werden, nicht blockieren. Siehe die Kommentare zu [this] (https://stackoverflow.com/q/40870990/6680611) Frage. – cartant

+1

Ich denke, dass er laufende Effekte und nicht wirklich Aktionen abbrechen will. Vielleicht, wenn Sie eine Aktion 'UPDATE_PROFILE' mit der Nutzlast' {newName: 'Some new name'} 'versenden, fängt einer Ihrer Effekte das ab und macht einen HTTP-Aufruf an die API. Aber sagen wir, die Anfrage dauert lange und der Benutzer klickt auf Disconnect. Wenn die vorherige Anfrage nach der Verbindungsunterbrechung beendet wird, wird Ihr (gereinigter) Shop aktualisiert. – Maxime

+0

@Maxime Ja, das ist genau das Problem, mit dem ich gerade konfrontiert bin –

Antwort

0

Ich basiere diese Antwort auf Maxime's comment, also hoffentlich habe ich Ihre Anforderungen richtig verstanden.

Ich hatte eine ähnliche Anforderung vor ein paar Tagen: verhindern Aktion Aktion von einem laufenden Effekt basierend auf der App-Status.
Außerdem brauchte ich etwas, um diese Logik in vielen Effekten zu verwenden, also musste es einfach zu verwenden sein.


Meine Lösung war, die Effektkette zu filtern, sobald die laufende Anfrage beendet ist. Jede Antwort wird ignoriert, sobald der Benutzer sich abgemeldet hat.

Zuerst habe ich einen Helfer-Klasse erstellt, die diese ‚ignore'-logic wickelt:

Effekt-helper.ts

import { Injectable } from '@angular/core'; 
import { Store } from '@ngrx/store'; 
import { Observable } from 'rxjs/Observable'; 
import { AppState } from 'app/reducers/root.reducer'; 

@Injectable() 
export class EffectHelper { 
    constructor(private store: Store<AppState>) { } 

    ignoreWhenLoggedOut<T>() { 
     return (source): Observable<T> => source 
      // get current app state 
      .withLatestFrom(this.store, (result, state) => ({ result, state })) 
      // only continue when user is logged in 
      .filter(combined => combined.state.auth !== undefined) 
      // pass on the result of the request when user is logged in 
      .map(combined => combined.result); 
    }; 
} 

ignoreWhenLoggedOut Die Methode nimmt eine beobachtbare Sequenz und Filter, wenn die auth -slice des globalen App-Status ist undefined. (In meinem Fall bedeutet ein undefinierter Auth-Zustand, dass kein Benutzer angemeldet ist).

Der Helfer kann nun in jedem Effekt verwendet werden, zum Beispiel:

my-effects.ts

import * as web from 'app/actions/web.action'; 
import { EffectHelper } from 'app/shared/effects-helper'; 

@Injectable() 
export class MyEffects { 

    @Effect() getWebRequest$ = this.actions$ 
     .ofType(web.WEB_REQUEST) 
     .map((action: web.WebRequestAction) => action.input) 
     .switchMap(input => this.svc.getWebRequest(input) 
      /* 
      * inject the ignore-logic into the effect 
      * notice that helper gets typed, so we have typesafety down the chain 
      */ 
      .let(this.effectHelper.ignoreWhenLoggedOut<MyResultType>()) 
      // this continues only when user is logged in 
      .map(result => new web.WebSuccessAction(result)) 
      .catch(error => { 
       return Observable.of(new web.WebFailureAction(error)); 
      }) 
     ); 

    constructor(
     private actions$: Actions, 
     private svc: WebService, 
     // inject effect-helper 
     private effectHelper: EffectHelper 
    ) { } 
} 

Wie Sie sehen können, kann ich jetzt alle laufende Wirkung von Dispatching weiter verhindern Aktionen mit einem Einzeiler dank dem let -Operator.

(Vergessen Sie nicht, EffectHelper in Ihrem Modul zur Verfügung zu stellen, wie Sie mit jedem anderen Dienst tun).

Verwandte Themen