如何解决 redux side-effects 重叠? (redux-observable)

How to solve redux side-effects overlapping? (redux-observable)

我有一个 Angular 4 应用程序,它使用 angular-router 在不同页面之间导航(我们称它们为 pageApageB )。 pageApageB 加载相同的项目列表 - sharedState.items(从时间重新加载时间)。这是这些页面的 redux 存储结构:

{
    pageA: { ... }
    pageB: { ..., noItemsMessage: null }
    sharedState: { items: [], popupMessage: null, ... }
}

当从服务器成功加载项目时,一切都很好(sharedState 得到更新,并且两个页面在导航到时都显示更改)。但是当服务器 returns 出错时会出现问题 - 我想在弹出窗口中的 pageA 上显示错误消息,使用 sharedState.popupMessage - 这是在应用程序的弹出窗口中显示错误的一般方式。但是在pageB上应该是一个小的本地工具提示,处于pageB.noItemsMessage状态属性.

我已 redux-observable epics 注册以收听 pageApageB[=38 的 'LOAD_ITEM_FAIL' 操作=] side-effects,但做不同的事情,例如:

pageALoadItemsFailEpic = actions$ => actions$.ofType('LOAD_ITEM_FAIL')
    .switchMap(x => { type: 'SHOW_POPUP', message: 'Error occured' })

pageBLoadItemsFailEpic = actions$ => actions$.ofType('LOAD_ITEM_FAIL')
        .switchMap(x => { type: 'UPDATE_PAGE_B_TOOLTIP', message: 'Error occured' })

问题是当我在 pageB 时 - 显示错误工具提示并弹出错误消息,因为 pageALoadItemsFailEpic 也被执行。 (而且我不想在 pageB 上显示弹出窗口。)

最简单的方法似乎是跟踪当前导航到的页面并据此执行副作用。但我想知道是否有更好的解决方案?或者是否有更好的方法来构建这种功能?有没有办法根据页面当前是否处于活动状态来打开 on/off epics?提前致谢!

我不使用 redux,而是使用 ngrx,但我很确定原理是相同的。

您不应该 show/hide UI 组件之外的元素。您应该做的是在您的州拥有属性,例如:

PageAErrors:any,
PageBErrors:any

然后您的 PageA 组件应该订阅 PageAErrors observable,页面 B 订阅 PageBErrors observable。然后每个组件自己决定在可观察到其兴趣(有错误)发出新值时做什么(弹出窗口、气球、工具提示等)。

始终坚持基本原则:这是一个松散耦合的消息传递架构,组件<>epics<>状态之间不应该有直接的命令式link。 epics 触发动作,这些动作反过来(通过 reducer)更新状态,组件监听状态变化并做出反应。

否则,您最终会在整个代码中维护 UI 仅属于组件的逻辑(例如弹出显示)。