如何解决 redux side-effects 重叠? (redux-observable)
How to solve redux side-effects overlapping? (redux-observable)
我有一个 Angular 4 应用程序,它使用 angular-router 在不同页面之间导航(我们称它们为 pageA 和 pageB )。 pageA 和 pageB 加载相同的项目列表 - sharedState.items(从时间重新加载时间)。这是这些页面的 redux 存储结构:
{
pageA: { ... }
pageB: { ..., noItemsMessage: null }
sharedState: { items: [], popupMessage: null, ... }
}
当从服务器成功加载项目时,一切都很好(sharedState 得到更新,并且两个页面在导航到时都显示更改)。但是当服务器 returns 出错时会出现问题 - 我想在弹出窗口中的 pageA 上显示错误消息,使用 sharedState.popupMessage - 这是在应用程序的弹出窗口中显示错误的一般方式。但是在pageB上应该是一个小的本地工具提示,处于pageB.noItemsMessage状态属性.
我已 redux-observable epics 注册以收听 pageA 和 pageB[=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 仅属于组件的逻辑(例如弹出显示)。
我有一个 Angular 4 应用程序,它使用 angular-router 在不同页面之间导航(我们称它们为 pageA 和 pageB )。 pageA 和 pageB 加载相同的项目列表 - sharedState.items(从时间重新加载时间)。这是这些页面的 redux 存储结构:
{
pageA: { ... }
pageB: { ..., noItemsMessage: null }
sharedState: { items: [], popupMessage: null, ... }
}
当从服务器成功加载项目时,一切都很好(sharedState 得到更新,并且两个页面在导航到时都显示更改)。但是当服务器 returns 出错时会出现问题 - 我想在弹出窗口中的 pageA 上显示错误消息,使用 sharedState.popupMessage - 这是在应用程序的弹出窗口中显示错误的一般方式。但是在pageB上应该是一个小的本地工具提示,处于pageB.noItemsMessage状态属性.
我已 redux-observable epics 注册以收听 pageA 和 pageB[=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 仅属于组件的逻辑(例如弹出显示)。