2017-06-09 25 views
1

ngrxでログアウトした後に発生するすべてのディスパッチアクションをブロックするにはどうしたらいいですか?このロジックを処理するルートディスパッチャがありますか?Ngrxはログアウトアクション後にディスパッチされたアクションをキャンセルします

+0

ストアに直接ディスパッチされたアクションをブロックすることはできません。 [this](https://stackoverflow.com/q/40870990/6680611)のコメントに関するコメントを参照してください。 – cartant

+1

私は彼が実際の行動ではなくエフェクトの実行をキャンセルしたいと思う。たとえば、ペイロード '{newName: 'いくつかの新しい名前'}'でアクションUPDATE_PROFILEをディスパッチした場合、エフェクトの1つがキャッチしてAPIにHTTP呼び出しを行います。しかし、それは長い時間がかかると、ユーザーが切断をクリックして要求を言う。切断された後に前のリクエストが終了しても、(クリーニングされた)ストアは更新されます。 – Maxime

+0

@Maximeはい、まさに私が今直面している問題です –

答えて

0

私はMaxime's commentでこの回答に基づいていますので、うまくいけば私はあなたの要件を正しく理解しました。

数日前に同様の要件がありました。は、アプリケーション状態に基づいて実行中のエフェクトからのアクションディスパッチを防止します。
さらに、私はこのロジックを多くのエフェクトで使用するために何かが必要なので、使用するのは簡単でなければなりませんでした。


私の解決策は、実行中のリクエストが終了したらエフェクトチェーンをフィルタリングすることでした。したがって、ユーザーがログアウトすると、応答は無視されます。

まず、私はこの「ignore'ロジックをラップするヘルパークラスを作成しました:

効果-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方法が観察シーケンスとフィルタを取りますauth - グローバルなapp-stateのスライスはundefinedです。 (私の場合は、未定義の認証状態とは、ユーザーがログインしていないことを意味します)。

ヘルパーは今例えば、任意の効果で使用できます。

私-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 
    ) { } 
} 

あなたが見ることができるように、私は今、さらに派遣から任意の実行中の影響を防ぐことができますlet - オペレーターのおかげで、1ライナーのアクション

(ほかのサービスと同じように、モジュールにEffectHelperを提供することを忘れないでください)。

関連する問題