ngrx - 有条件地停止/删除效果/动作 [英] ngrx - conditionally stop/remove Effect/Action

查看:92
本文介绍了ngrx - 有条件地停止/删除效果/动作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在使用Ionic2和ngrx构建一个应用程序,如果没有网络连接,我正在尝试停止certian操作。

I am currently building an application with Ionic2 and ngrx and I am trying to stop certian Actions if there is no network connection.

停止我的意思是以某种方式制作它们对其他效果和商店不可见或阻止它们进一步传播。

With stop I mean to somehow make them invisible for other Effects and the store or stop them from further "propagating".

有没有办法做这样的事情?

Is there a way to do something like this?

@Effect()
checkNetworkConnection$ = this.actions$
  .ofType(book.ActionTypes.LOAD_BOOKS, book.ActionTypes.CREATE_BOOK)
  .if(Network.connection === 'none')
  .do(() => new ShowNetworkAlertAction()) //Returns ShowNetworkAlertAction
  .stopPropagation(); // Removes the Action from the stream

stopPropagation()应该以某种方式从流中删除Action,之后应该就像是从未调度过该动作一样。甚至商店也不应该改变任何东西或执行将在此Action上执行的代码。

stopPropagation() should somehow "remove" the Action from the stream, after that it should be like if the action has never been dispatched. Even the store should not change anything or execute the code that would be executed on this Action.

推荐答案

一个解决方案是添加网络在线/离线到州(或以其他方式作为可观察流提供)。然后你可以在你的效果中使用 takeUntil ,当你离线时需要忽略动作。

One solution would be to add network online/offline to the state (or have it otherwise available as an observable stream). Then you could use takeUntil in your effects that need to ignore actions when you're offline.

精神在上面的示例中,您可以尝试这样的事情(未经测试,但应该关闭):

In the spirit of the example above, you could try something like this (untested, but should be close):

// NOTE: This effect listens for `LOAD_BOOKS` command actions, and emits the
// `PROGRESS` and either `LOAD_BOOKS_SUCCESS` or `LOAD_BOOKS_FAILURE` event actions 
// that the reducers will listen for.
@Effect()
loadBooksWhenOnline$ = this.actions$
    .ofType('LOAD_BOOKS')
    .map(action => action.payload)
    .withLatestFrom(this.store$)
    .filter(([payload, state]) => state.network.status === 'online')
    .switchMap(([payload, state]) => {
        const networkOffline$ = this.actions$.ofType('NETWORK')
            .filter(action => action.payload === 'offline');

        const someOtherReasonToCancel$ = this.actions$.ofType('CANCEL');

        const stop$ = Observable.merge(networkOffline$, someOtherReasonToCancel$);

        return Observable.concat(
            Observable.of({ type: 'PROGRESS', payload: { isLoading: true } }),
            this.bookService.getBooks$(payload)
                .map(books => ({ type: 'LOAD_BOOKS_SUCCESS', payload: books }))
                .catch(err => Observable.of({ type: 'LOAD_BOOKS_FAILURE', payload: { payload, err })
                .takeUntil(stop$),
            Observable.of({ type: 'PROGRESS', payload: { isLoading: false } }),
        );
    })
    .observeOn(async); // may want this, depending on how your actions interact

// elsewhere in reducerville
export function reducer(state, action) {
    switch (action.type) {
        case 'LOAD_BOOKS_SUCCESS':
            return reduceLoadBooksSuccessAction(state, action);
        case 'LOAD_BOOKS_FAILURE':
            return reduceLoadBooksFailureAction(state, action);
        case 'PROGRESS':
            return Object.assign({}, state, {
                progress: Object.assign({}, state.progress, action.payload)
            });
        // ...
        default:
            return state;
    }
}

有一个初始过滤器检查状态只是为了制作确定你实际上在线,然后通过 takeUntil 进行下线。我还添加了一个额外的CANCEL操作,以显示如何因多种原因停止效果。

There's an initial filter check with the state just to make sure you're actually online, and then going offline later happens via takeUntil. I also added an additional CANCEL action just to show how to stop the effect for multiple reasons.

此外,上面的示例假设一个模型,其中效果处理请求操作(即命令)和reducers是处理'结果'动作(即事件)的纯函数。

Also, the above example assumes a model where effects handle 'request' actions (i.e. commands) and the reducers are pure functions that handle the 'result' actions (i.e. events).

更新2:好的,我添加了一个简单的 isLoading 带有相应reducer的进度标志,如请求的那样。具体来说,添加 Observable.concat 调用将使用 isLoading 状态更改来包装图书服务查询。进度操作也可能有其他进度标志,此示例仅更新 isLoading 属性。

UPDATE 2: Ok, I added a simple isLoading progress flag with a corresponding reducer, as requested. Specifically, the addition of the Observable.concat call wraps the book service query with isLoading state changes. The progress action could also have other progress flags as well, and this example only updates the isLoading property.

这篇关于ngrx - 有条件地停止/删除效果/动作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆