注销操作后,Ngrx取消已发送的操作

时间:2017-06-09 10:18:35

标签: redux ngrx

如何在ngrx中阻止我的注销操作后触发的所有已调度操作?是否存在某种处理此逻辑的根调度程序?

1 个答案:

答案 0 :(得分:0)

我的答案基于Maxime's comment,所以希望我能正确理解你的要求。

几天前我有类似的要求:根据app-state 阻止运行效果的任何动作调度。
另外,我需要在很多效果中使用这个逻辑,所以它必须简单易用。

我的解决方案是在运行请求完成后过滤效果链。因此,一旦用户退出,任何响应都会被忽略。

首先,我创建了一个帮助类,它包含了这个'ignore'-logic:

<强>效果-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方法采用Observable序列,并在全局app-state的auth - 切片为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 - 运算符,我现在可以通过单行调度来阻止任何运行效果。

(不要忘记在模块中提供EffectHelper,就像使用任何其他服务一样。)