ngrx - 有条件地停止/删除效果/动作

Das*_*kus 2 rxjs redux ionic2 ngrx angular

我目前正在使用Ionic2和ngrx构建一个应用程序,如果没有网络连接,我试图阻止certian Actions.

有了停止,我的意思是以某种方式使它们对其他效果和商店不可见或阻止它们进一步"传播".

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

@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
Run Code Online (Sandbox Code Playgroud)

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

rob*_*b3c 7

一种解决方案是将网络在线/离线添加到状态(或者将其作为可观察流提供).然后,您可以使用takeUntil需要在离线时忽略操作的效果.

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

// 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;
    }
}
Run Code Online (Sandbox Code Playgroud)

对状态进行初始过滤检查只是为了确保您确实在线,然后通过以后离线takeUntil.我还添加了一个额外的CANCEL动作,以显示如何因多种原因停止效果.

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

更新2:好的,我isLoading根据要求添加了一个带有相应reducer 的简单进度标志.具体来说,添加Observable.concat调用会使书籍服务查询包含isLoading状态更改.进度操作也可以有其他进度标志,此示例仅更新isLoading属性.